X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fbackends%2Fportaudio%2Fportaudio_io.cc;h=a7c4516b53f9a4d0d29b9fd5f6648e8b76d9a847;hb=6b7875de1e0af7622b8c3a054633f522cb96de30;hp=d8a7fc9cf140c280ec06f051707b9da4fdc557ce;hpb=46c83693284ece4a732d26e62113ea4ac584d539;p=ardour.git diff --git a/libs/backends/portaudio/portaudio_io.cc b/libs/backends/portaudio/portaudio_io.cc index d8a7fc9cf1..a7c4516b53 100644 --- a/libs/backends/portaudio/portaudio_io.cc +++ b/libs/backends/portaudio/portaudio_io.cc @@ -51,10 +51,7 @@ PortAudioIO::~PortAudioIO () Pa_Terminate(); } - for (std::map::const_iterator i = _devices.begin (); i != _devices.end(); ++i) { - delete i->second; - } - _devices.clear(); + clear_device_lists (); free (_input_buffer); _input_buffer = NULL; free (_output_buffer); _output_buffer = NULL; @@ -70,7 +67,7 @@ PortAudioIO::available_sample_rates(int device_id, std::vector& sampleRat // TODO use separate int device_input, int device_output ?! if (device_id == -1) { - device_id = Pa_GetDefaultInputDevice(); + device_id = get_default_input_device (); } #ifndef NDEBUG printf("PortAudio: Querying Samplerates for device %d\n", device_id); @@ -126,43 +123,143 @@ PortAudioIO::available_buffer_sizes(int device_id, std::vector& buffer } void -PortAudioIO::device_list (std::map &devices) const { - devices.clear(); - for (std::map::const_iterator i = _devices.begin (); i != _devices.end(); ++i) { - devices.insert (std::pair (i->first, Glib::locale_to_utf8(i->second->name))); +PortAudioIO::input_device_list(std::map &devices) const +{ + for (std::map::const_iterator i = _input_devices.begin (); + i != _input_devices.end (); + ++i) { + devices.insert (std::pair(i->first, Glib::locale_to_utf8(i->second->name))); } } void -PortAudioIO::discover() +PortAudioIO::output_device_list(std::map &devices) const { - for (std::map::const_iterator i = _devices.begin (); i != _devices.end(); ++i) { - delete i->second; + for (std::map::const_iterator i = _output_devices.begin (); + i != _output_devices.end (); + ++i) { + devices.insert (std::pair(i->first, Glib::locale_to_utf8(i->second->name))); } - _devices.clear(); - +} + +bool +PortAudioIO::initialize_pa () +{ PaError err = paNoError; if (!_initialized) { err = Pa_Initialize(); + if (err != paNoError) { + return false; + } + _initialized = true; } - if (err != paNoError) { - return; + + return true; +} + +void +PortAudioIO::host_api_list (std::vector& api_list) +{ + if (!initialize_pa()) return; + + PaHostApiIndex count = Pa_GetHostApiCount(); + + if (count < 0) return; + + for (int i = 0; i < count; ++i) { + const PaHostApiInfo* info = Pa_GetHostApiInfo (i); + if (info->name != NULL) { // possible? + api_list.push_back (info->name); + } } +} - _initialized = true; +void +PortAudioIO::set_host_api (const std::string& host_api_name) +{ + _host_api_index = get_host_api_index_from_name (host_api_name); - { - const PaDeviceInfo* nfo_i = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice()); - const PaDeviceInfo* nfo_o = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice()); - if (nfo_i && nfo_o) { - _devices.insert (std::pair (-1, - new paDevice("Default", - nfo_i->maxInputChannels, - nfo_o->maxOutputChannels - ))); + if (_host_api_index < 0) { + fprintf(stderr, "Error setting host API\n"); + } +} + +PaHostApiIndex +PortAudioIO::get_host_api_index_from_name (const std::string& name) +{ + if (!initialize_pa()) return -1; + + PaHostApiIndex count = Pa_GetHostApiCount(); + + if (count < 0) return -1; + + for (int i = 0; i < count; ++i) { + const PaHostApiInfo* info = Pa_GetHostApiInfo (i); + if (info->name != NULL) { // possible? + if (name == info->name) return i; } } + 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 +PortAudioIO::clear_device_lists () +{ + for (std::map::const_iterator i = _input_devices.begin (); i != _input_devices.end(); ++i) { + delete i->second; + } + _input_devices.clear(); + + for (std::map::const_iterator i = _output_devices.begin (); i != _output_devices.end(); ++i) { + delete i->second; + } + _output_devices.clear(); +} + +void +PortAudioIO::add_default_devices () +{ + const PaHostApiInfo* info = Pa_GetHostApiInfo (_host_api_index); + if (info == NULL) return; + + const PaDeviceInfo* nfo_i = Pa_GetDeviceInfo(get_default_input_device()); + const PaDeviceInfo* nfo_o = Pa_GetDeviceInfo(get_default_output_device()); + if (nfo_i && nfo_o) { + _input_devices.insert (std::pair (-1, + new paDevice("Default", + nfo_i->maxInputChannels, + nfo_o->maxOutputChannels + ))); + _output_devices.insert (std::pair (-1, + new paDevice("Default", + nfo_i->maxInputChannels, + nfo_o->maxOutputChannels + ))); + } +} + +void +PortAudioIO::add_devices () +{ + const PaHostApiInfo* info = Pa_GetHostApiInfo (_host_api_index); + if (info == NULL) return; int n_devices = Pa_GetDeviceCount(); #ifndef NDEBUG @@ -171,10 +268,12 @@ PortAudioIO::discover() for (int i = 0 ; i < n_devices; ++i) { const PaDeviceInfo* nfo = Pa_GetDeviceInfo(i); + if (!nfo) continue; + if (nfo->hostApi != _host_api_index) continue; #ifndef NDEBUG - printf(" (%d) '%s' in: %d (lat: %.1f .. %.1f) out: %d (lat: %.1f .. %.1f) sr:%.2f\n", - i, nfo->name, + printf(" (%d) '%s' '%s' in: %d (lat: %.1f .. %.1f) out: %d (lat: %.1f .. %.1f) sr:%.2f\n", + i, info->name, nfo->name, nfo->maxInputChannels, nfo->defaultLowInputLatency * 1e3, nfo->defaultHighInputLatency * 1e3, @@ -186,14 +285,34 @@ PortAudioIO::discover() if ( nfo->maxInputChannels == 0 && nfo->maxOutputChannels == 0) { continue; } - _devices.insert (std::pair (i, new paDevice( - nfo->name, - nfo->maxInputChannels, - nfo->maxOutputChannels - ))); + + if (nfo->maxInputChannels > 0) { + _input_devices.insert (std::pair (i, new paDevice( + nfo->name, + nfo->maxInputChannels, + nfo->maxOutputChannels + ))); + } + if (nfo->maxOutputChannels > 0) { + _output_devices.insert (std::pair (i, new paDevice( + nfo->name, + nfo->maxInputChannels, + nfo->maxOutputChannels + ))); + } } } +void +PortAudioIO::discover() +{ + if (!initialize_pa()) return; + + clear_device_lists (); + add_default_devices (); + add_devices (); +} + void PortAudioIO::pcm_stop () { @@ -252,21 +371,16 @@ PortAudioIO::pcm_setup ( const PaDeviceInfo *nfo_out; const PaStreamInfo *nfo_s; - if (!_initialized) { - err = Pa_Initialize(); - } - if (err != paNoError) { + if (!initialize_pa()) { fprintf(stderr, "PortAudio Initialization Failed\n"); goto error; } - _initialized = true; - if (device_input == -1) { - device_input = Pa_GetDefaultInputDevice(); + device_input = get_default_input_device (); } if (device_output == -1) { - device_output = Pa_GetDefaultOutputDevice(); + device_output = get_default_output_device (); } _capture_channels = 0; @@ -405,7 +519,6 @@ error: _playback_channels = 0; free (_input_buffer); _input_buffer = NULL; free (_output_buffer); _output_buffer = NULL; - Pa_Terminate(); return -1; }