From a378cac92d6b8dc033d86391a6e6607fb24719ea Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 4 Aug 2015 12:25:15 -0700 Subject: [PATCH] JACK: fix not setting outstream buffer_duration --- soundio/soundio.h | 18 ++++++++------ src/jack.cpp | 6 ++--- src/soundio.cpp | 63 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/soundio/soundio.h b/soundio/soundio.h index 2101d35..f8585a8 100644 --- a/soundio/soundio.h +++ b/soundio/soundio.h @@ -397,12 +397,14 @@ struct SoundIoOutStream { // Buffer duration in seconds. // After you call `soundio_outstream_open` this value is replaced with the // actual duration, as near to this value as possible. - // Defaults to 1 second (and then clamped into range). + // Defaults to a big buffer, potentially upwards of 1 second. If you want + // lower latency, set this value to the latency you want. // If the device has unknown buffer duration min and max values, you may - // still set this. If you set this and the backend is PulseAudio, it - // sets `PA_STREAM_ADJUST_LATENCY` and is the value used for `maxlength` - // and `tlength`. With PulseAudio, this value is not replaced with the - // actual duration until `soundio_outstream_start`. + // still set this, but you might not get the value you requested. If you + // set this and the backend is PulseAudio, it sets + // `PA_STREAM_ADJUST_LATENCY` and is the value used for `maxlength` and + // `tlength`. With PulseAudio, this value is not replaced with the actual + // duration until `soundio_outstream_start`. double buffer_duration; // `period_duration` is the latency; how much time it takes @@ -657,11 +659,13 @@ int soundio_output_device_count(struct SoundIo *soundio); // Always returns a device. Call soundio_device_unref when done. // `index` must be 0 <= index < soundio_input_device_count -// Returns NULL if you never called `soundio_flush_events`. +// Returns NULL if you never called `soundio_flush_events` or if you provide +// invalid parameter values. struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int index); // Always returns a device. Call soundio_device_unref when done. // `index` must be 0 <= index < soundio_output_device_count -// Returns NULL if you never called `soundio_flush_events`. +// Returns NULL if you never called `soundio_flush_events` or if you provide +// invalid parameter values. struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int index); // returns the index of the default input device diff --git a/src/jack.cpp b/src/jack.cpp index c1ffd91..4418e8e 100644 --- a/src/jack.cpp +++ b/src/jack.cpp @@ -99,7 +99,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { return SoundIoErrorNoMem; } - SoundIoList clients; + SoundIoList clients = {0}; const char **port_name_ptr = port_names; while (*port_name_ptr) { const char *client_and_port_name = *port_name_ptr; @@ -415,7 +415,7 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; - outstream->buffer_duration = 0.0; + outstream->buffer_duration = device->period_duration_current; outstream->period_duration = device->period_duration_current; osj->period_size = sij->period_size; @@ -616,7 +616,7 @@ static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamP if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; - instream->buffer_duration = 0.0; + instream->buffer_duration = device->period_duration_current; instream->period_duration = device->period_duration_current; isj->period_size = sij->period_size; diff --git a/src/soundio.cpp b/src/soundio.cpp index 4e7009a..90cd407 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -254,43 +254,75 @@ void soundio_flush_events(struct SoundIo *soundio) { } int soundio_input_device_count(struct SoundIo *soundio) { - assert(soundio->current_backend != SoundIoBackendNone); SoundIoPrivate *si = (SoundIoPrivate *)soundio; + + assert(si->safe_devices_info); if (!si->safe_devices_info) return -1; + + assert(soundio->current_backend != SoundIoBackendNone); + if (soundio->current_backend == SoundIoBackendNone) + return -1; + return si->safe_devices_info->input_devices.length; } int soundio_output_device_count(struct SoundIo *soundio) { - assert(soundio->current_backend != SoundIoBackendNone); SoundIoPrivate *si = (SoundIoPrivate *)soundio; + + assert(si->safe_devices_info); if (!si->safe_devices_info) return -1; + + assert(soundio->current_backend != SoundIoBackendNone); + if (soundio->current_backend == SoundIoBackendNone) + return -1; + return si->safe_devices_info->output_devices.length; } int soundio_default_input_device_index(struct SoundIo *soundio) { - assert(soundio->current_backend != SoundIoBackendNone); SoundIoPrivate *si = (SoundIoPrivate *)soundio; + + assert(si->safe_devices_info); if (!si->safe_devices_info) return -1; + + assert(soundio->current_backend != SoundIoBackendNone); + if (soundio->current_backend == SoundIoBackendNone) + return -1; + return si->safe_devices_info->default_input_index; } int soundio_default_output_device_index(struct SoundIo *soundio) { - assert(soundio->current_backend != SoundIoBackendNone); SoundIoPrivate *si = (SoundIoPrivate *)soundio; + + assert(si->safe_devices_info); if (!si->safe_devices_info) return -1; + + assert(soundio->current_backend != SoundIoBackendNone); + if (soundio->current_backend == SoundIoBackendNone) + return -1; + return si->safe_devices_info->default_output_index; } struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int index) { SoundIoPrivate *si = (SoundIoPrivate *)soundio; + assert(soundio->current_backend != SoundIoBackendNone); + if (soundio->current_backend == SoundIoBackendNone) + return nullptr; + + assert(si->safe_devices_info); + if (!si->safe_devices_info) + return nullptr; + assert(index >= 0); assert(index < si->safe_devices_info->input_devices.length); - if (!si->safe_devices_info) + if (index < 0 || index >= si->safe_devices_info->input_devices.length) return nullptr; SoundIoDevice *device = si->safe_devices_info->input_devices.at(index); @@ -300,10 +332,18 @@ struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int inde struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int index) { SoundIoPrivate *si = (SoundIoPrivate *)soundio; + assert(soundio->current_backend != SoundIoBackendNone); + if (soundio->current_backend == SoundIoBackendNone) + return nullptr; + + assert(si->safe_devices_info); + if (!si->safe_devices_info) + return nullptr; + assert(index >= 0); assert(index < si->safe_devices_info->output_devices.length); - if (!si->safe_devices_info) + if (index < 0 || index >= si->safe_devices_info->output_devices.length) return nullptr; SoundIoDevice *device = si->safe_devices_info->output_devices.at(index); @@ -333,6 +373,7 @@ void soundio_device_unref(struct SoundIoDevice *device) { } void soundio_device_ref(struct SoundIoDevice *device) { + assert(device); device->ref_count += 1; } @@ -370,9 +411,12 @@ static void default_underflow_callback(struct SoundIoOutStream *outstream) { } struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device) { SoundIoOutStreamPrivate *os = allocate(1); + SoundIoOutStream *outstream = &os->pub; + if (!os) return nullptr; - SoundIoOutStream *outstream = &os->pub; + if (!device) + return nullptr; outstream->device = device; soundio_device_ref(device); @@ -455,9 +499,12 @@ static void default_instream_error_callback(struct SoundIoInStream *is, int err) struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device) { SoundIoInStreamPrivate *is = allocate(1); + SoundIoInStream *instream = &is->pub; + if (!is) return nullptr; - SoundIoInStream *instream = &is->pub; + if (!device) + return nullptr; instream->device = device; soundio_device_ref(device);