From 0bc918e2c8320bb446fc861109ad833bcdd2edaa Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 16 Jul 2015 23:37:17 -0700 Subject: [PATCH] better list_devices behavior --- example/list_devices.c | 10 ++++++++ src/alsa.cpp | 57 ++++++++++++++++++------------------------ src/soundio.h | 1 - 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/example/list_devices.c b/example/list_devices.c index 64eff5b..e54a00e 100644 --- a/example/list_devices.c +++ b/example/list_devices.c @@ -62,6 +62,16 @@ static void print_device(struct SoundIoDevice *device, bool is_default) { fprintf(stderr, "\n"); if (device->current_format != SoundIoFormatInvalid) fprintf(stderr, " current format: %s\n", soundio_format_string(device->current_format)); + + fprintf(stderr, " min buffer duration: %0.8f sec\n", device->buffer_duration_min); + fprintf(stderr, " max buffer duration: %0.8f sec\n", device->buffer_duration_max); + if (device->buffer_duration_current != 0.0) + fprintf(stderr, " current buffer duration: %0.8f sec\n", device->buffer_duration_current); + + fprintf(stderr, " min period duration: %0.8f sec\n", device->period_duration_min); + fprintf(stderr, " max period duration: %0.8f sec\n", device->period_duration_max); + if (device->period_duration_current != 0.0) + fprintf(stderr, " current period duration: %0.8f sec\n", device->period_duration_current); } fprintf(stderr, "\n"); } diff --git a/src/alsa.cpp b/src/alsa.cpp index cfd80eb..ee3104c 100644 --- a/src/alsa.cpp +++ b/src/alsa.cpp @@ -261,11 +261,12 @@ static void test_fmt_mask(SoundIoDevice *device, const snd_pcm_format_mask_t *fm } // this function does not override device->formats, so if you want it to, deallocate and set it to NULL -static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, - snd_pcm_hw_params_t *hwparams, int resample) -{ +static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resample) { int err; + snd_pcm_hw_params_t *hwparams; + snd_pcm_hw_params_alloca(&hwparams); + if ((err = snd_pcm_hw_params_any(handle, hwparams)) < 0) return SoundIoErrorOpeningDevice; @@ -281,32 +282,26 @@ static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, if ((err = snd_pcm_hw_params_set_channels_last(handle, hwparams, &channel_count)) < 0) return SoundIoErrorOpeningDevice; - unsigned int num; - unsigned int den; + unsigned int rate_min; + unsigned int rate_max; - int dir = 0; - if ((err = snd_pcm_hw_params_set_rate_first(handle, hwparams, &num, &dir)) < 0) + if ((err = snd_pcm_hw_params_get_rate_min(hwparams, &rate_min, nullptr)) < 0) return SoundIoErrorOpeningDevice; - if ((err = snd_pcm_hw_params_get_rate_numden(hwparams, &num, &den)) < 0) + if ((err = snd_pcm_hw_params_get_rate_max(hwparams, &rate_max, nullptr)) < 0) return SoundIoErrorOpeningDevice; - if (den != 1) - return SoundIoErrorIncompatibleDevice; + device->sample_rate_min = rate_min; + device->sample_rate_max = rate_max; - device->sample_rate_min = num; - - dir = 0; - if ((err = snd_pcm_hw_params_set_rate_last(handle, hwparams, &num, &dir)) < 0) + if ((err = snd_pcm_hw_params_set_rate_last(handle, hwparams, &rate_max, nullptr)) < 0) return SoundIoErrorOpeningDevice; - if ((err = snd_pcm_hw_params_get_rate_numden(hwparams, &num, &den)) < 0) + rate_max = 48000; + if ((err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate_max, nullptr)) < 0) return SoundIoErrorOpeningDevice; - if (den != 1) - return SoundIoErrorIncompatibleDevice; - - device->sample_rate_max = num; + double one_over_actual_rate = 1.0 / (double)rate_max; // Purposefully leave the parameters with the highest rate, highest channel count. @@ -322,19 +317,23 @@ static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, if ((err = snd_pcm_hw_params_get_period_size_max(hwparams, &max_frames, nullptr)) < 0) return SoundIoErrorIncompatibleDevice; + device->period_duration_min = min_frames * one_over_actual_rate; + device->period_duration_max = max_frames * one_over_actual_rate; + + if ((err = snd_pcm_hw_params_set_period_size_first(handle, hwparams, &min_frames, nullptr)) < 0) + return SoundIoErrorIncompatibleDevice; - device->period_duration_min = ((double)min_frames) / (double)device->sample_rate_max; - device->period_duration_max = ((double)max_frames) / (double)device->sample_rate_max; if ((err = snd_pcm_hw_params_get_buffer_size_min(hwparams, &min_frames)) < 0) return SoundIoErrorOpeningDevice; if ((err = snd_pcm_hw_params_get_buffer_size_max(hwparams, &max_frames)) < 0) return SoundIoErrorOpeningDevice; - // divide the frame counts by the max sample rate - device->buffer_duration_min = ((double)min_frames) / (double)device->sample_rate_max; - device->buffer_duration_max = ((double)max_frames) / (double)device->sample_rate_max; + device->buffer_duration_min = min_frames * one_over_actual_rate; + device->buffer_duration_max = max_frames * one_over_actual_rate; + if ((err = snd_pcm_hw_params_set_buffer_size_first(handle, hwparams, &min_frames)) < 0) + return SoundIoErrorOpeningDevice; snd_pcm_format_mask_t *fmt_mask; @@ -396,12 +395,6 @@ static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { int err; snd_pcm_t *handle; - snd_pcm_hw_params_t *hwparams; - snd_pcm_sw_params_t *swparams; - - snd_pcm_hw_params_alloca(&hwparams); - snd_pcm_sw_params_alloca(&swparams); - snd_pcm_stream_t stream = purpose_to_stream(device->purpose); if ((err = snd_pcm_open(&handle, device->name, stream, 0)) < 0) { @@ -409,7 +402,7 @@ static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { return SoundIoErrorOpeningDevice; } - if ((err = probe_open_device(device, handle, hwparams, 0))) { + if ((err = probe_open_device(device, handle, 0))) { handle_channel_maps(device, maps); snd_pcm_close(handle); return err; @@ -440,7 +433,7 @@ static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { device->period_duration_current = device->period_duration_min; // now say that resampling is OK and see what the real min and max is. - if ((err = probe_open_device(device, handle, hwparams, 1)) < 0) { + if ((err = probe_open_device(device, handle, 1)) < 0) { snd_pcm_close(handle); return SoundIoErrorOpeningDevice; } diff --git a/src/soundio.h b/src/soundio.h index c5ced1c..ff058bb 100644 --- a/src/soundio.h +++ b/src/soundio.h @@ -449,7 +449,6 @@ const char * soundio_format_string(enum SoundIoFormat format); // Devices -// returns -1 on error int soundio_get_input_device_count(struct SoundIo *soundio); int soundio_get_output_device_count(struct SoundIo *soundio);