Set default input/output device based on selected host api rather than global default

This commit is contained in:
Tim Mayberry 2015-04-01 22:56:45 +10:00
parent e2001ac4f3
commit 4e370feeb1
4 changed files with 45 additions and 22 deletions

View file

@ -112,14 +112,14 @@ PortAudioBackend::enumerate_drivers () const
int int
PortAudioBackend::set_driver (const std::string& name) PortAudioBackend::set_driver (const std::string& name)
{ {
_target_driver = name; _pcmio->set_host_api (name);
return 0; return 0;
} }
std::vector<AudioBackend::DeviceStatus> std::vector<AudioBackend::DeviceStatus>
PortAudioBackend::enumerate_devices () const PortAudioBackend::enumerate_devices () const
{ {
_pcmio->discover(_target_driver); _pcmio->discover();
_audio_device_status.clear(); _audio_device_status.clear();
std::map<int, std::string> devices; std::map<int, std::string> devices;
_pcmio->device_list(devices); _pcmio->device_list(devices);

View file

@ -317,7 +317,6 @@ class PortAudioBackend : public AudioBackend {
static std::vector<AudioBackend::DeviceStatus> _audio_device_status; static std::vector<AudioBackend::DeviceStatus> _audio_device_status;
static std::vector<AudioBackend::DeviceStatus> _midi_device_status; static std::vector<AudioBackend::DeviceStatus> _midi_device_status;
std::string _target_driver;
mutable std::string _audio_device; mutable std::string _audio_device;
std::string _midi_driver_option; std::string _midi_driver_option;

View file

@ -70,7 +70,7 @@ PortAudioIO::available_sample_rates(int device_id, std::vector<float>& sampleRat
// TODO use separate int device_input, int device_output ?! // TODO use separate int device_input, int device_output ?!
if (device_id == -1) { if (device_id == -1) {
device_id = Pa_GetDefaultInputDevice(); device_id = get_default_input_device ();
} }
#ifndef NDEBUG #ifndef NDEBUG
printf("PortAudio: Querying Samplerates for device %d\n", device_id); printf("PortAudio: Querying Samplerates for device %d\n", device_id);
@ -166,6 +166,16 @@ PortAudioIO::host_api_list (std::vector<std::string>& api_list)
} }
} }
void
PortAudioIO::set_host_api (const std::string& host_api_name)
{
_host_api_index = get_host_api_index_from_name (host_api_name);
if (_host_api_index < 0) {
fprintf(stderr, "Error setting host API\n");
}
}
PaHostApiIndex PaHostApiIndex
PortAudioIO::get_host_api_index_from_name (const std::string& name) PortAudioIO::get_host_api_index_from_name (const std::string& name)
{ {
@ -184,8 +194,24 @@ PortAudioIO::get_host_api_index_from_name (const std::string& name)
return -1; return -1;
} }
PaDeviceIndex
PortAudioIO::get_default_input_device ()
{
const PaHostApiInfo* info = Pa_GetHostApiInfo (_host_api_index);
if (info == NULL) return -1;
return info->defaultInputDevice;
}
PaDeviceIndex
PortAudioIO::get_default_output_device ()
{
const PaHostApiInfo* info = Pa_GetHostApiInfo (_host_api_index);
if (info == NULL) return -1;
return info->defaultOutputDevice;
}
void void
PortAudioIO::discover(const std::string& host_api) PortAudioIO::discover()
{ {
if (!initialize_pa()) return; if (!initialize_pa()) return;
@ -194,19 +220,12 @@ PortAudioIO::discover(const std::string& host_api)
} }
_devices.clear(); _devices.clear();
PaHostApiIndex host_api_index = get_host_api_index_from_name (host_api); const PaHostApiInfo* info = Pa_GetHostApiInfo (_host_api_index);
if (host_api_index < 0) return;
const PaHostApiInfo* info = Pa_GetHostApiInfo (host_api_index);
if (info == NULL) return; if (info == NULL) return;
PaDeviceIndex default_input = info->defaultInputDevice;
PaDeviceIndex default_output = info->defaultOutputDevice;
{ {
const PaDeviceInfo* nfo_i = Pa_GetDeviceInfo(default_input); const PaDeviceInfo* nfo_i = Pa_GetDeviceInfo(get_default_input_device());
const PaDeviceInfo* nfo_o = Pa_GetDeviceInfo(default_output); const PaDeviceInfo* nfo_o = Pa_GetDeviceInfo(get_default_output_device());
if (nfo_i && nfo_o) { if (nfo_i && nfo_o) {
_devices.insert (std::pair<int, paDevice*> (-1, _devices.insert (std::pair<int, paDevice*> (-1,
new paDevice("Default", new paDevice("Default",
@ -225,10 +244,10 @@ PortAudioIO::discover(const std::string& host_api)
const PaDeviceInfo* nfo = Pa_GetDeviceInfo(i); const PaDeviceInfo* nfo = Pa_GetDeviceInfo(i);
if (!nfo) continue; if (!nfo) continue;
if (nfo->hostApi != host_api_index) continue; if (nfo->hostApi != _host_api_index) continue;
#ifndef NDEBUG #ifndef NDEBUG
printf(" (%d) '%s' in: %d (lat: %.1f .. %.1f) out: %d (lat: %.1f .. %.1f) sr:%.2f\n", printf(" (%d) '%s' '%s' in: %d (lat: %.1f .. %.1f) out: %d (lat: %.1f .. %.1f) sr:%.2f\n",
i, nfo->name, i, info->name, nfo->name,
nfo->maxInputChannels, nfo->maxInputChannels,
nfo->defaultLowInputLatency * 1e3, nfo->defaultLowInputLatency * 1e3,
nfo->defaultHighInputLatency * 1e3, nfo->defaultHighInputLatency * 1e3,
@ -312,10 +331,10 @@ PortAudioIO::pcm_setup (
} }
if (device_input == -1) { if (device_input == -1) {
device_input = Pa_GetDefaultInputDevice(); device_input = get_default_input_device ();
} }
if (device_output == -1) { if (device_output == -1) {
device_output = Pa_GetDefaultOutputDevice(); device_output = get_default_output_device ();
} }
_capture_channels = 0; _capture_channels = 0;

View file

@ -40,9 +40,13 @@ public:
bool initialize_pa (); bool initialize_pa ();
void host_api_list (std::vector<std::string>&); void host_api_list (std::vector<std::string>&);
void set_host_api (const std::string& host_api_name);
PaHostApiIndex get_host_api_index_from_name (const std::string& name); PaHostApiIndex get_host_api_index_from_name (const std::string& name);
void discover(const std::string& host_api); PaDeviceIndex get_default_input_device ();
PaDeviceIndex get_default_output_device ();
void discover();
void device_list (std::map<int, std::string> &devices) const; void device_list (std::map<int, std::string> &devices) const;
int available_sample_rates (int device_id, std::vector<float>& sampleRates); int available_sample_rates (int device_id, std::vector<float>& sampleRates);
@ -102,7 +106,8 @@ private:
std::map<int, paDevice *> _devices; std::map<int, paDevice *> _devices;
std::string _host_api; PaHostApiIndex _host_api_index;
}; };
} // namespace } // namespace