diff --git a/example/list_devices.c b/example/list_devices.c index f542b2d..c68a057 100644 --- a/example/list_devices.c +++ b/example/list_devices.c @@ -87,9 +87,14 @@ int main(int argc, char **argv) { } } + struct SoundIo *soundio = soundio_create(); + if (!soundio) { + fprintf(stderr, "out of memory\n"); + return 1; + } + int err; - struct SoundIo *soundio; - if ((err = soundio_create(&soundio))) { + if ((err = soundio_connect(soundio))) { fprintf(stderr, "%s\n", soundio_error_string(err)); return err; } diff --git a/src/dummy.cpp b/src/dummy.cpp index 5dd6ee3..3a4efbd 100644 --- a/src/dummy.cpp +++ b/src/dummy.cpp @@ -89,15 +89,8 @@ static void destroy_dummy(SoundIo *soundio) { if (sid->mutex) soundio_os_mutex_destroy(sid->mutex); - if (soundio->safe_devices_info) { - for (int i = 0; i < soundio->safe_devices_info->input_devices.length; i += 1) - soundio_device_unref(soundio->safe_devices_info->input_devices.at(i)); - for (int i = 0; i < soundio->safe_devices_info->output_devices.length; i += 1) - soundio_device_unref(soundio->safe_devices_info->output_devices.at(i)); - destroy(soundio->safe_devices_info); - soundio->safe_devices_info = nullptr; - } - + destroy(sid); + soundio->backend_data = nullptr; } static void flush_events(SoundIo *soundio) { @@ -379,4 +372,3 @@ int soundio_dummy_init(SoundIo *soundio) { return 0; } - diff --git a/src/soundio.cpp b/src/soundio.cpp index b8b6bf5..e23efde 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -54,6 +54,7 @@ const char * soundio_sample_format_string(enum SoundIoSampleFormat sample_format const char *soundio_backend_name(enum SoundIoBackend backend) { switch (backend) { + case SoundIoBackendNone: return "(none)"; case SoundIoBackendPulseAudio: return "PulseAudio"; case SoundIoBackendDummy: return "Dummy"; } @@ -64,39 +65,78 @@ void soundio_destroy(struct SoundIo *soundio) { if (!soundio) return; - if (soundio->destroy) - soundio->destroy(soundio); + soundio_disconnect(soundio); destroy(soundio); } -int soundio_create(struct SoundIo **out_soundio) { - *out_soundio = NULL; - +struct SoundIo * soundio_create(void) { struct SoundIo *soundio = create(); if (!soundio) { soundio_destroy(soundio); - return SoundIoErrorNoMem; + return NULL; } + return soundio; +} +int soundio_connect(struct SoundIo *soundio) { int err; + soundio->current_backend = SoundIoBackendPulseAudio; err = soundio_pulseaudio_init(soundio); if (err != SoundIoErrorInitAudioBackend) { - soundio_destroy(soundio); + soundio_disconnect(soundio); return err; } + soundio->current_backend = SoundIoBackendDummy; err = soundio_dummy_init(soundio); if (err) { - soundio_destroy(soundio); + soundio_disconnect(soundio); return err; } - *out_soundio = soundio; return 0; } +void soundio_disconnect(struct SoundIo *soundio) { + if (soundio->destroy) + soundio->destroy(soundio); + assert(!soundio->backend_data); + + soundio->current_backend = SoundIoBackendNone; + + if (soundio->safe_devices_info) { + for (int i = 0; i < soundio->safe_devices_info->input_devices.length; i += 1) + soundio_device_unref(soundio->safe_devices_info->input_devices.at(i)); + for (int i = 0; i < soundio->safe_devices_info->output_devices.length; i += 1) + soundio_device_unref(soundio->safe_devices_info->output_devices.at(i)); + destroy(soundio->safe_devices_info); + soundio->safe_devices_info = nullptr; + } + + soundio->destroy = nullptr; + soundio->flush_events = nullptr; + soundio->wait_events = nullptr; + soundio->wakeup = nullptr; + soundio->refresh_devices = nullptr; + + soundio->output_device_init = nullptr; + soundio->output_device_destroy = nullptr; + soundio->output_device_start = nullptr; + soundio->output_device_free_count = nullptr; + soundio->output_device_begin_write = nullptr; + soundio->output_device_write = nullptr; + soundio->output_device_clear_buffer = nullptr; + + soundio->input_device_init = nullptr; + soundio->input_device_destroy = nullptr; + soundio->input_device_start = nullptr; + soundio->input_device_peek = nullptr; + soundio->input_device_drop = nullptr; + soundio->input_device_clear_buffer = nullptr; +} + void soundio_flush_events(struct SoundIo *soundio) { if (soundio->flush_events) soundio->flush_events(soundio); diff --git a/src/soundio.h b/src/soundio.h index 001e071..38fa1c5 100644 --- a/src/soundio.h +++ b/src/soundio.h @@ -88,6 +88,7 @@ enum SoundIoChannelLayoutId { }; enum SoundIoBackend { + SoundIoBackendNone, SoundIoBackendPulseAudio, SoundIoBackendDummy, }; @@ -145,7 +146,6 @@ struct SoundIoInputDevice { struct SoundIo { enum SoundIoBackend current_backend; - void *backend_data; // safe to read without a mutex from a single thread struct SoundIoDevicesInfo *safe_devices_info; @@ -154,6 +154,8 @@ struct SoundIo { void (*on_devices_change)(struct SoundIo *); void (*on_events_signal)(struct SoundIo *); + + void *backend_data; void (*destroy)(struct SoundIo *); void (*flush_events)(struct SoundIo *); void (*wait_events)(struct SoundIo *); @@ -184,10 +186,12 @@ struct SoundIo { // Create a SoundIo context. // Returns an error code. -int soundio_create(struct SoundIo **out_soundio); - +struct SoundIo * soundio_create(void); void soundio_destroy(struct SoundIo *soundio); +int soundio_connect(struct SoundIo *soundio); +void soundio_disconnect(struct SoundIo *soundio); + const char *soundio_error_string(int error); const char *soundio_backend_name(enum SoundIoBackend backend);