summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-04-01 16:55:34 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-07-31 09:59:54 +1000
commitb6db19a5c67e4b58bc2555d7ff83f97bdba6811b (patch)
tree33f7eb2d71ae40282fda685622680692dd169b04
parent2437bbbe2315a4f9991874ea8baa5d91230bc139 (diff)
Add host api/driver selection to PortaudioBackend
-rw-r--r--libs/backends/portaudio/portaudio_backend.cc29
-rw-r--r--libs/backends/portaudio/portaudio_backend.h5
-rw-r--r--libs/backends/portaudio/portaudio_io.cc78
-rw-r--r--libs/backends/portaudio/portaudio_io.h9
4 files changed, 107 insertions, 14 deletions
diff --git a/libs/backends/portaudio/portaudio_backend.cc b/libs/backends/portaudio/portaudio_backend.cc
index 0277ca1270..3e24ff28f0 100644
--- a/libs/backends/portaudio/portaudio_backend.cc
+++ b/libs/backends/portaudio/portaudio_backend.cc
@@ -89,10 +89,37 @@ PortAudioBackend::is_realtime () const
return true;
}
+bool
+PortAudioBackend::requires_driver_selection() const
+{
+ // we could do this but implementation would need changing
+ /*
+ if (enumerate_drivers().size() == 1) {
+ return false;
+ }
+ */
+ return true;
+}
+
+std::vector<std::string>
+PortAudioBackend::enumerate_drivers () const
+{
+ std::vector<std::string> currently_available;
+ _pcmio->host_api_list (currently_available);
+ return currently_available;
+}
+
+int
+PortAudioBackend::set_driver (const std::string& name)
+{
+ _target_driver = name;
+ return 0;
+}
+
std::vector<AudioBackend::DeviceStatus>
PortAudioBackend::enumerate_devices () const
{
- _pcmio->discover();
+ _pcmio->discover(_target_driver);
_audio_device_status.clear();
std::map<int, std::string> devices;
_pcmio->device_list(devices);
diff --git a/libs/backends/portaudio/portaudio_backend.h b/libs/backends/portaudio/portaudio_backend.h
index 36aebe0f14..432598263d 100644
--- a/libs/backends/portaudio/portaudio_backend.h
+++ b/libs/backends/portaudio/portaudio_backend.h
@@ -160,6 +160,10 @@ class PortAudioBackend : public AudioBackend {
std::string name () const;
bool is_realtime () const;
+ bool requires_driver_selection() const;
+ std::vector<std::string> enumerate_drivers () const;
+ int set_driver (const std::string&);
+
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;
@@ -313,6 +317,7 @@ class PortAudioBackend : public AudioBackend {
static std::vector<AudioBackend::DeviceStatus> _audio_device_status;
static std::vector<AudioBackend::DeviceStatus> _midi_device_status;
+ std::string _target_driver;
mutable std::string _audio_device;
std::string _midi_driver_option;
diff --git a/libs/backends/portaudio/portaudio_io.cc b/libs/backends/portaudio/portaudio_io.cc
index d8a7fc9cf1..0b2256496d 100644
--- a/libs/backends/portaudio/portaudio_io.cc
+++ b/libs/backends/portaudio/portaudio_io.cc
@@ -133,28 +133,80 @@ PortAudioIO::device_list (std::map<int, std::string> &devices) const {
}
}
-void
-PortAudioIO::discover()
+bool
+PortAudioIO::initialize_pa ()
{
- for (std::map<int, paDevice*>::const_iterator i = _devices.begin (); i != _devices.end(); ++i) {
- delete i->second;
- }
- _devices.clear();
-
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<std::string>& 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;
+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;
+}
+
+void
+PortAudioIO::discover(const std::string& host_api)
+{
+ if (!initialize_pa()) return;
+
+ for (std::map<int, paDevice*>::const_iterator i = _devices.begin (); i != _devices.end(); ++i) {
+ delete i->second;
+ }
+ _devices.clear();
+
+ PaHostApiIndex host_api_index = get_host_api_index_from_name (host_api);
+
+ if (host_api_index < 0) return;
+
+ const PaHostApiInfo* info = Pa_GetHostApiInfo (host_api_index);
+
+ if (info == NULL) return;
+ PaDeviceIndex default_input = info->defaultInputDevice;
+ PaDeviceIndex default_output = info->defaultOutputDevice;
{
- const PaDeviceInfo* nfo_i = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice());
- const PaDeviceInfo* nfo_o = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
+ const PaDeviceInfo* nfo_i = Pa_GetDeviceInfo(default_input);
+ const PaDeviceInfo* nfo_o = Pa_GetDeviceInfo(default_output);
if (nfo_i && nfo_o) {
_devices.insert (std::pair<int, paDevice*> (-1,
new paDevice("Default",
@@ -171,7 +223,9 @@ 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,
diff --git a/libs/backends/portaudio/portaudio_io.h b/libs/backends/portaudio/portaudio_io.h
index 532dc66df6..bbc3f9a4d0 100644
--- a/libs/backends/portaudio/portaudio_io.h
+++ b/libs/backends/portaudio/portaudio_io.h
@@ -37,7 +37,12 @@ public:
int state (void) const { return _state; }
- void discover();
+ bool initialize_pa ();
+
+ void host_api_list (std::vector<std::string>&);
+ PaHostApiIndex get_host_api_index_from_name (const std::string& name);
+
+ void discover(const std::string& host_api);
void device_list (std::map<int, std::string> &devices) const;
int available_sample_rates (int device_id, std::vector<float>& sampleRates);
@@ -96,6 +101,8 @@ private:
};
std::map<int, paDevice *> _devices;
+
+ std::string _host_api;
};
} // namespace