implement getting audio device counts

This commit is contained in:
Andrew Kelley 2015-07-01 01:20:26 -07:00
parent e409400f04
commit d36493e1fe
5 changed files with 62 additions and 34 deletions

View file

@ -54,7 +54,10 @@ static void recording_thread_run(void *arg) {
} }
*/ */
static void destroy_audio_hardware_dummy(SoundIo *soundio) { } static void destroy_dummy(SoundIo *soundio) {
destroy(soundio->safe_devices_info);
soundio->safe_devices_info = nullptr;
}
static void flush_events(SoundIo *soundio) { } static void flush_events(SoundIo *soundio) { }
@ -197,8 +200,14 @@ static void input_device_clear_buffer_dummy(SoundIo *soundio,
// TODO // TODO
} }
int audio_hardware_init_dummy(SoundIo *soundio) { int soundio_dummy_init(SoundIo *soundio) {
assert(!soundio->safe_devices_info);
soundio->safe_devices_info = create<SoundIoDevicesInfo>(); soundio->safe_devices_info = create<SoundIoDevicesInfo>();
if (!soundio->safe_devices_info) {
destroy_dummy(soundio);
return SoundIoErrorNoMem;
}
soundio->safe_devices_info->default_input_index = 0; soundio->safe_devices_info->default_input_index = 0;
soundio->safe_devices_info->default_output_index = 0; soundio->safe_devices_info->default_output_index = 0;
@ -223,7 +232,7 @@ int audio_hardware_init_dummy(SoundIo *soundio) {
device->default_sample_rate = 48000; device->default_sample_rate = 48000;
device->purpose = SoundIoDevicePurposeOutput; device->purpose = SoundIoDevicePurposeOutput;
if (soundio->safe_devices_info->devices.append(device)) { if (soundio->safe_devices_info->output_devices.append(device)) {
soundio_audio_device_unref(device); soundio_audio_device_unref(device);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
@ -250,14 +259,14 @@ int audio_hardware_init_dummy(SoundIo *soundio) {
device->default_sample_rate = 48000; device->default_sample_rate = 48000;
device->purpose = SoundIoDevicePurposeInput; device->purpose = SoundIoDevicePurposeInput;
if (soundio->safe_devices_info->devices.append(device)) { if (soundio->safe_devices_info->input_devices.append(device)) {
soundio_audio_device_unref(device); soundio_audio_device_unref(device);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
} }
soundio->destroy = destroy_audio_hardware_dummy; soundio->destroy = destroy_dummy;
soundio->flush_events = flush_events; soundio->flush_events = flush_events;
soundio->refresh_audio_devices = refresh_audio_devices; soundio->refresh_audio_devices = refresh_audio_devices;

View file

@ -24,7 +24,7 @@ struct SoundIoOutputDeviceDummy {
}; };
struct SoundIoInputDeviceDummy { struct SoundIoInputDeviceDummy {
// TODO
}; };
int soundio_dummy_init(struct SoundIo *soundio); int soundio_dummy_init(struct SoundIo *soundio);

View file

@ -62,8 +62,10 @@ static void context_state_callback(pa_context *context, void *userdata) {
static void destroy_current_audio_devices_info(SoundIo *soundio) { static void destroy_current_audio_devices_info(SoundIo *soundio) {
SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data; SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data;
if (ah->current_audio_devices_info) { if (ah->current_audio_devices_info) {
for (int i = 0; i < ah->current_audio_devices_info->devices.length; i += 1) for (int i = 0; i < ah->current_audio_devices_info->input_devices.length; i += 1)
soundio_audio_device_unref(ah->current_audio_devices_info->devices.at(i)); soundio_audio_device_unref(ah->current_audio_devices_info->input_devices.at(i));
for (int i = 0; i < ah->current_audio_devices_info->output_devices.length; i += 1)
soundio_audio_device_unref(ah->current_audio_devices_info->output_devices.at(i));
destroy(ah->current_audio_devices_info); destroy(ah->current_audio_devices_info);
ah->current_audio_devices_info = nullptr; ah->current_audio_devices_info = nullptr;
@ -73,15 +75,17 @@ static void destroy_current_audio_devices_info(SoundIo *soundio) {
static void destroy_ready_audio_devices_info(SoundIo *soundio) { static void destroy_ready_audio_devices_info(SoundIo *soundio) {
SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data; SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data;
if (ah->ready_audio_devices_info) { if (ah->ready_audio_devices_info) {
for (int i = 0; i < ah->ready_audio_devices_info->devices.length; i += 1) for (int i = 0; i < ah->ready_audio_devices_info->input_devices.length; i += 1)
soundio_audio_device_unref(ah->ready_audio_devices_info->devices.at(i)); soundio_audio_device_unref(ah->ready_audio_devices_info->input_devices.at(i));
for (int i = 0; i < ah->ready_audio_devices_info->output_devices.length; i += 1)
soundio_audio_device_unref(ah->ready_audio_devices_info->output_devices.at(i));
destroy(ah->ready_audio_devices_info); destroy(ah->ready_audio_devices_info);
ah->ready_audio_devices_info = nullptr; ah->ready_audio_devices_info = nullptr;
} }
} }
static void destroy_audio_hardware_pa(SoundIo *soundio) { static void destroy_pa(SoundIo *soundio) {
SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data; SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data;
if (ah->main_loop) if (ah->main_loop)
pa_threaded_mainloop_stop(ah->main_loop); pa_threaded_mainloop_stop(ah->main_loop);
@ -193,18 +197,20 @@ static void finish_device_query(SoundIo *soundio) {
// based on the default sink name, figure out the default output index // based on the default sink name, figure out the default output index
ah->current_audio_devices_info->default_output_index = -1; ah->current_audio_devices_info->default_output_index = -1;
ah->current_audio_devices_info->default_input_index = -1; ah->current_audio_devices_info->default_input_index = -1;
for (int i = 0; i < ah->current_audio_devices_info->devices.length; i += 1) { for (int i = 0; i < ah->current_audio_devices_info->input_devices.length; i += 1) {
SoundIoDevice *device = ah->current_audio_devices_info->devices.at(i); SoundIoDevice *device = ah->current_audio_devices_info->input_devices.at(i);
if (device->purpose == SoundIoDevicePurposeOutput && assert(device->purpose == SoundIoDevicePurposeInput);
strcmp(device->name, ah->default_sink_name) == 0) if (strcmp(device->name, ah->default_source_name) == 0) {
{
ah->current_audio_devices_info->default_output_index = i;
} else if (device->purpose == SoundIoDevicePurposeInput &&
strcmp(device->name, ah->default_source_name) == 0)
{
ah->current_audio_devices_info->default_input_index = i; ah->current_audio_devices_info->default_input_index = i;
} }
} }
for (int i = 0; i < ah->current_audio_devices_info->output_devices.length; i += 1) {
SoundIoDevice *device = ah->current_audio_devices_info->output_devices.at(i);
assert(device->purpose == SoundIoDevicePurposeOutput);
if (strcmp(device->name, ah->default_sink_name) == 0) {
ah->current_audio_devices_info->default_output_index = i;
}
}
destroy_ready_audio_devices_info(soundio); destroy_ready_audio_devices_info(soundio);
ah->ready_audio_devices_info = ah->current_audio_devices_info; ah->ready_audio_devices_info = ah->current_audio_devices_info;
@ -237,7 +243,7 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in
device->default_sample_rate = sample_rate_from_pulseaudio(info->sample_spec); device->default_sample_rate = sample_rate_from_pulseaudio(info->sample_spec);
device->purpose = SoundIoDevicePurposeOutput; device->purpose = SoundIoDevicePurposeOutput;
if (ah->current_audio_devices_info->devices.append(device)) if (ah->current_audio_devices_info->output_devices.append(device))
panic("out of memory"); panic("out of memory");
} }
pa_threaded_mainloop_signal(ah->main_loop, 0); pa_threaded_mainloop_signal(ah->main_loop, 0);
@ -266,7 +272,7 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info
device->default_sample_rate = sample_rate_from_pulseaudio(info->sample_spec); device->default_sample_rate = sample_rate_from_pulseaudio(info->sample_spec);
device->purpose = SoundIoDevicePurposeInput; device->purpose = SoundIoDevicePurposeInput;
if (ah->current_audio_devices_info->devices.append(device)) if (ah->current_audio_devices_info->input_devices.append(device))
panic("out of memory"); panic("out of memory");
} }
pa_threaded_mainloop_signal(ah->main_loop, 0); pa_threaded_mainloop_signal(ah->main_loop, 0);
@ -350,8 +356,10 @@ static void flush_events(SoundIo *soundio) {
soundio->on_devices_change(soundio); soundio->on_devices_change(soundio);
if (old_devices_info) { if (old_devices_info) {
for (int i = 0; i < old_devices_info->devices.length; i += 1) for (int i = 0; i < old_devices_info->input_devices.length; i += 1)
soundio_audio_device_unref(old_devices_info->devices.at(i)); soundio_audio_device_unref(old_devices_info->input_devices.at(i));
for (int i = 0; i < old_devices_info->output_devices.length; i += 1)
soundio_audio_device_unref(old_devices_info->output_devices.at(i));
destroy(old_devices_info); destroy(old_devices_info);
} }
} }
@ -788,7 +796,7 @@ static void refresh_audio_devices(SoundIo *soundio) {
block_until_have_devices(soundio); block_until_have_devices(soundio);
} }
int audio_hardware_init_pulseaudio(SoundIo *soundio) { int soundio_pulseaudio_init(SoundIo *soundio) {
SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data; SoundIoPulseAudio *ah = (SoundIoPulseAudio *)soundio->backend_data;
ah->connection_refused = false; ah->connection_refused = false;
@ -798,7 +806,7 @@ int audio_hardware_init_pulseaudio(SoundIo *soundio) {
ah->main_loop = pa_threaded_mainloop_new(); ah->main_loop = pa_threaded_mainloop_new();
if (!ah->main_loop) { if (!ah->main_loop) {
destroy_audio_hardware_pa(soundio); destroy_pa(soundio);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
@ -806,7 +814,7 @@ int audio_hardware_init_pulseaudio(SoundIo *soundio) {
ah->props = pa_proplist_new(); ah->props = pa_proplist_new();
if (!ah->props) { if (!ah->props) {
destroy_audio_hardware_pa(soundio); destroy_pa(soundio);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
@ -817,7 +825,7 @@ int audio_hardware_init_pulseaudio(SoundIo *soundio) {
ah->pulse_context = pa_context_new_with_proplist(main_loop_api, "SoundIo", ah->props); ah->pulse_context = pa_context_new_with_proplist(main_loop_api, "SoundIo", ah->props);
if (!ah->pulse_context) { if (!ah->pulse_context) {
destroy_audio_hardware_pa(soundio); destroy_pa(soundio);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
@ -826,21 +834,21 @@ int audio_hardware_init_pulseaudio(SoundIo *soundio) {
int err = pa_context_connect(ah->pulse_context, NULL, (pa_context_flags_t)0, NULL); int err = pa_context_connect(ah->pulse_context, NULL, (pa_context_flags_t)0, NULL);
if (err) { if (err) {
destroy_audio_hardware_pa(soundio); destroy_pa(soundio);
return SoundIoErrorInitAudioBackend; return SoundIoErrorInitAudioBackend;
} }
if (ah->connection_refused) { if (ah->connection_refused) {
destroy_audio_hardware_pa(soundio); destroy_pa(soundio);
return SoundIoErrorInitAudioBackend; return SoundIoErrorInitAudioBackend;
} }
if (pa_threaded_mainloop_start(ah->main_loop)) { if (pa_threaded_mainloop_start(ah->main_loop)) {
destroy_audio_hardware_pa(soundio); destroy_pa(soundio);
return SoundIoErrorNoMem; return SoundIoErrorNoMem;
} }
soundio->destroy = destroy_audio_hardware_pa; soundio->destroy = destroy_pa;
soundio->flush_events = flush_events; soundio->flush_events = flush_events;
soundio->refresh_audio_devices = refresh_audio_devices; soundio->refresh_audio_devices = refresh_audio_devices;

View file

@ -5,7 +5,7 @@
* See http://opensource.org/licenses/MIT * See http://opensource.org/licenses/MIT
*/ */
#include "soundio.h" #include "soundio.hpp"
#include "util.hpp" #include "util.hpp"
#include "dummy.hpp" #include "dummy.hpp"
#include "pulseaudio.hpp" #include "pulseaudio.hpp"
@ -472,3 +472,13 @@ void soundio_flush_events(struct SoundIo *soundio) {
if (soundio->flush_events) if (soundio->flush_events)
soundio->flush_events(soundio); soundio->flush_events(soundio);
} }
int soundio_get_input_device_count(struct SoundIo *soundio) {
assert(soundio->safe_devices_info);
return soundio->safe_devices_info->input_devices.length;
}
int soundio_get_output_device_count(struct SoundIo *soundio) {
assert(soundio->safe_devices_info);
return soundio->safe_devices_info->output_devices.length;
}

View file

@ -12,7 +12,8 @@
#include "list.hpp" #include "list.hpp"
struct SoundIoDevicesInfo { struct SoundIoDevicesInfo {
SoundIoList<SoundIoDevice *> devices; SoundIoList<SoundIoDevice *> input_devices;
SoundIoList<SoundIoDevice *> output_devices;
// can be -1 when default device is unknown // can be -1 when default device is unknown
int default_output_index; int default_output_index;
int default_input_index; int default_input_index;