diff options
-rw-r--r-- | gtk2_ardour/engine_dialog.cc | 29 | ||||
-rw-r--r-- | libs/ardour/ardour/audio_backend.h | 19 | ||||
-rw-r--r-- | libs/ardour/ardour/jack_audiobackend.h | 7 | ||||
-rw-r--r-- | libs/ardour/jack_audiobackend.cc | 37 |
4 files changed, 76 insertions, 16 deletions
diff --git a/gtk2_ardour/engine_dialog.cc b/gtk2_ardour/engine_dialog.cc index 3a06fb5072..8c67d23d36 100644 --- a/gtk2_ardour/engine_dialog.cc +++ b/gtk2_ardour/engine_dialog.cc @@ -280,14 +280,29 @@ EngineControl::list_devices () /* now fill out devices, mark sample rates, buffer sizes insensitive */ - vector<string> devices = backend->enumerate_devices (); + vector<ARDOUR::AudioBackend::DeviceStatus> all_devices = backend->enumerate_devices (); - set_popdown_strings (interface_combo, devices); - interface_combo.set_active_text (devices.front()); - set_popdown_strings (input_device_combo, devices); - input_device_combo.set_active_text (devices.front()); - set_popdown_strings (output_device_combo, devices); - output_device_combo.set_active_text (devices.front()); + /* NOTE: Ardour currently does not display the "available" field of the + * returned devices. + * + * Doing so would require a different GUI widget than the combo + * box/popdown that we currently use, since it has no way to list + * items that are not selectable. Something more like a popup menu, + * which could have unselectable items, would be appropriate. + */ + + vector<string> available_devices; + + for (vector<ARDOUR::AudioBackend::DeviceStatus>::const_iterator i = all_devices.begin(); i != all_devices.end(); ++i) { + available_devices.push_back (i->name); + } + + set_popdown_strings (interface_combo, available_devices); + interface_combo.set_active_text (available_devices.front()); + set_popdown_strings (input_device_combo, available_devices); + input_device_combo.set_active_text (available_devices.front()); + set_popdown_strings (output_device_combo, available_devices); + output_device_combo.set_active_text (available_devices.front()); interface_changed (); } diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index 08dd7fb0b5..77b7eadb48 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -95,12 +95,25 @@ class AudioBackend { */ virtual int set_driver (const std::string& /*drivername*/) { return 0; } - /** Returns a collection of strings identifying devices known - * to this backend. Any of these strings may be used to identify a + /** used to list device names along with whether or not they are currently + * available. + */ + struct DeviceStatus { + std::string name; + bool available; + + DeviceStatus (const std::string& s, bool avail) : name (s), available (avail) {} + }; + + /** Returns a collection of DeviceStatuses identifying devices discovered + * by this backend since the start of the process. + * + * Any of the names in each DeviceStatus may be used to identify a * device in other calls to the backend, though any of them may become * invalid at any time. */ - virtual std::vector<std::string> enumerate_devices () const = 0; + virtual std::vector<DeviceStatus> enumerate_devices () const = 0; + /** Returns a collection of float identifying sample rates that are * potentially usable with the hardware identified by @param device. * Any of these values may be supplied in other calls to this backend diff --git a/libs/ardour/ardour/jack_audiobackend.h b/libs/ardour/ardour/jack_audiobackend.h index 59b5b88105..9fa3d0c1cc 100644 --- a/libs/ardour/ardour/jack_audiobackend.h +++ b/libs/ardour/ardour/jack_audiobackend.h @@ -23,6 +23,7 @@ #include <string> #include <vector> #include <map> +#include <set> #include <stdint.h> @@ -53,7 +54,7 @@ class JACKAudioBackend : public AudioBackend { std::vector<std::string> enumerate_drivers () const; int set_driver (const std::string&); - std::vector<std::string> enumerate_devices () const; + std::vector<DeviceStatus> enumerate_devices () const; std::vector<float> available_sample_rates (const std::string& device) const; std::vector<uint32_t> available_buffer_sizes (const std::string& device) const; @@ -172,7 +173,11 @@ class JACKAudioBackend : public AudioBackend { uint32_t _current_usecs_per_cycle; uint32_t _current_systemic_input_latency; uint32_t _current_systemic_output_latency; + + typedef std::set<std::string> DeviceList; + typedef std::map<std::string,DeviceList> DriverDeviceMap; + mutable DriverDeviceMap all_devices; }; } // namespace diff --git a/libs/ardour/jack_audiobackend.cc b/libs/ardour/jack_audiobackend.cc index 8ab8428555..19158aacc9 100644 --- a/libs/ardour/jack_audiobackend.cc +++ b/libs/ardour/jack_audiobackend.cc @@ -97,9 +97,9 @@ JACKAudioBackend::requires_driver_selection() const vector<string> JACKAudioBackend::enumerate_drivers () const { - vector<string> s; - get_jack_audio_driver_names (s); - return s; + vector<string> currently_available; + get_jack_audio_driver_names (currently_available); + return currently_available; } int @@ -109,10 +109,37 @@ JACKAudioBackend::set_driver (const std::string& name) return 0; } -vector<string> +vector<AudioBackend::DeviceStatus> JACKAudioBackend::enumerate_devices () const { - return get_jack_device_names_for_audio_driver (_target_driver); + vector<string> currently_available = get_jack_device_names_for_audio_driver (_target_driver); + vector<DeviceStatus> statuses; + + if (all_devices.find (_target_driver) == all_devices.end()) { + all_devices.insert (make_pair (_target_driver, std::set<string>())); + } + + /* store every device we've found, by driver name. + * + * This is so we do not confuse ALSA, FFADO, netjack etc. devices + * with each other. + */ + + DeviceList& all (all_devices[_target_driver]); + + for (vector<string>::const_iterator d = currently_available.begin(); d != currently_available.end(); ++d) { + all.insert (*d); + } + + for (DeviceList::const_iterator d = all.begin(); d != all.end(); ++d) { + if (find (currently_available.begin(), currently_available.end(), *d) == currently_available.end()) { + statuses.push_back (DeviceStatus (*d, false)); + } else { + statuses.push_back (DeviceStatus (*d, false)); + } + } + + return statuses; } vector<float> |