better list_devices behavior

This commit is contained in:
Andrew Kelley 2015-07-16 23:37:17 -07:00
parent 46a6a179b6
commit 0bc918e2c8
3 changed files with 35 additions and 33 deletions

View file

@ -62,6 +62,16 @@ static void print_device(struct SoundIoDevice *device, bool is_default) {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (device->current_format != SoundIoFormatInvalid) if (device->current_format != SoundIoFormatInvalid)
fprintf(stderr, " current format: %s\n", soundio_format_string(device->current_format)); 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"); fprintf(stderr, "\n");
} }

View file

@ -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 // 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, static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resample) {
snd_pcm_hw_params_t *hwparams, int resample)
{
int err; int err;
snd_pcm_hw_params_t *hwparams;
snd_pcm_hw_params_alloca(&hwparams);
if ((err = snd_pcm_hw_params_any(handle, hwparams)) < 0) if ((err = snd_pcm_hw_params_any(handle, hwparams)) < 0)
return SoundIoErrorOpeningDevice; 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) if ((err = snd_pcm_hw_params_set_channels_last(handle, hwparams, &channel_count)) < 0)
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
unsigned int num; unsigned int rate_min;
unsigned int den; unsigned int rate_max;
int dir = 0; if ((err = snd_pcm_hw_params_get_rate_min(hwparams, &rate_min, nullptr)) < 0)
if ((err = snd_pcm_hw_params_set_rate_first(handle, hwparams, &num, &dir)) < 0)
return SoundIoErrorOpeningDevice; 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; return SoundIoErrorOpeningDevice;
if (den != 1) device->sample_rate_min = rate_min;
return SoundIoErrorIncompatibleDevice; device->sample_rate_max = rate_max;
device->sample_rate_min = num; if ((err = snd_pcm_hw_params_set_rate_last(handle, hwparams, &rate_max, nullptr)) < 0)
dir = 0;
if ((err = snd_pcm_hw_params_set_rate_last(handle, hwparams, &num, &dir)) < 0)
return SoundIoErrorOpeningDevice; 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; return SoundIoErrorOpeningDevice;
if (den != 1) double one_over_actual_rate = 1.0 / (double)rate_max;
return SoundIoErrorIncompatibleDevice;
device->sample_rate_max = num;
// Purposefully leave the parameters with the highest rate, highest channel count. // 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) if ((err = snd_pcm_hw_params_get_period_size_max(hwparams, &max_frames, nullptr)) < 0)
return SoundIoErrorIncompatibleDevice; 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) if ((err = snd_pcm_hw_params_get_buffer_size_min(hwparams, &min_frames)) < 0)
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
if ((err = snd_pcm_hw_params_get_buffer_size_max(hwparams, &max_frames)) < 0) if ((err = snd_pcm_hw_params_get_buffer_size_max(hwparams, &max_frames)) < 0)
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
// divide the frame counts by the max sample rate device->buffer_duration_min = min_frames * one_over_actual_rate;
device->buffer_duration_min = ((double)min_frames) / (double)device->sample_rate_max; device->buffer_duration_max = max_frames * one_over_actual_rate;
device->buffer_duration_max = ((double)max_frames) / (double)device->sample_rate_max;
if ((err = snd_pcm_hw_params_set_buffer_size_first(handle, hwparams, &min_frames)) < 0)
return SoundIoErrorOpeningDevice;
snd_pcm_format_mask_t *fmt_mask; 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; int err;
snd_pcm_t *handle; 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); snd_pcm_stream_t stream = purpose_to_stream(device->purpose);
if ((err = snd_pcm_open(&handle, device->name, stream, 0)) < 0) { 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; return SoundIoErrorOpeningDevice;
} }
if ((err = probe_open_device(device, handle, hwparams, 0))) { if ((err = probe_open_device(device, handle, 0))) {
handle_channel_maps(device, maps); handle_channel_maps(device, maps);
snd_pcm_close(handle); snd_pcm_close(handle);
return err; 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; device->period_duration_current = device->period_duration_min;
// now say that resampling is OK and see what the real min and max is. // 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); snd_pcm_close(handle);
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
} }

View file

@ -449,7 +449,6 @@ const char * soundio_format_string(enum SoundIoFormat format);
// Devices // Devices
// returns -1 on error
int soundio_get_input_device_count(struct SoundIo *soundio); int soundio_get_input_device_count(struct SoundIo *soundio);
int soundio_get_output_device_count(struct SoundIo *soundio); int soundio_get_output_device_count(struct SoundIo *soundio);