add notion of unavailable devices to ARDOUR::AudioBackend

This commit is contained in:
Paul Davis 2013-08-05 13:19:23 -04:00
parent a66e3859e1
commit a5f69910e4
4 changed files with 76 additions and 16 deletions

View file

@ -280,14 +280,29 @@ EngineControl::list_devices ()
/* now fill out devices, mark sample rates, buffer sizes insensitive */ /* 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); /* NOTE: Ardour currently does not display the "available" field of the
interface_combo.set_active_text (devices.front()); * returned devices.
set_popdown_strings (input_device_combo, devices); *
input_device_combo.set_active_text (devices.front()); * Doing so would require a different GUI widget than the combo
set_popdown_strings (output_device_combo, devices); * box/popdown that we currently use, since it has no way to list
output_device_combo.set_active_text (devices.front()); * 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 (); interface_changed ();
} }

View file

@ -95,12 +95,25 @@ class AudioBackend {
*/ */
virtual int set_driver (const std::string& /*drivername*/) { return 0; } virtual int set_driver (const std::string& /*drivername*/) { return 0; }
/** Returns a collection of strings identifying devices known /** used to list device names along with whether or not they are currently
* to this backend. Any of these strings may be used to identify a * 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 * device in other calls to the backend, though any of them may become
* invalid at any time. * 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 /** Returns a collection of float identifying sample rates that are
* potentially usable with the hardware identified by @param device. * potentially usable with the hardware identified by @param device.
* Any of these values may be supplied in other calls to this backend * Any of these values may be supplied in other calls to this backend

View file

@ -23,6 +23,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <set>
#include <stdint.h> #include <stdint.h>
@ -53,7 +54,7 @@ class JACKAudioBackend : public AudioBackend {
std::vector<std::string> enumerate_drivers () const; std::vector<std::string> enumerate_drivers () const;
int set_driver (const std::string&); 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<float> available_sample_rates (const std::string& device) const;
std::vector<uint32_t> available_buffer_sizes (const std::string& device) const; std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
@ -173,6 +174,10 @@ class JACKAudioBackend : public AudioBackend {
uint32_t _current_systemic_input_latency; uint32_t _current_systemic_input_latency;
uint32_t _current_systemic_output_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 } // namespace

View file

@ -97,9 +97,9 @@ JACKAudioBackend::requires_driver_selection() const
vector<string> vector<string>
JACKAudioBackend::enumerate_drivers () const JACKAudioBackend::enumerate_drivers () const
{ {
vector<string> s; vector<string> currently_available;
get_jack_audio_driver_names (s); get_jack_audio_driver_names (currently_available);
return s; return currently_available;
} }
int int
@ -109,10 +109,37 @@ JACKAudioBackend::set_driver (const std::string& name)
return 0; return 0;
} }
vector<string> vector<AudioBackend::DeviceStatus>
JACKAudioBackend::enumerate_devices () const 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> vector<float>