diff --git a/soundio/soundio.h b/soundio/soundio.h index c5a285d..ba1acbe 100644 --- a/soundio/soundio.h +++ b/soundio/soundio.h @@ -496,7 +496,8 @@ struct SoundIoOutStream { enum SoundIoFormat format; /// Sample rate is the number of frames per second. - /// Defaults to 48000 (and then clamped into range). + /// Defaults to SoundIoDevice::sample_rate_current if available, + /// otherwise 44100 clamped into range. int sample_rate; /// Defaults to Stereo, if available, followed by the first layout @@ -598,7 +599,8 @@ struct SoundIoInStream { enum SoundIoFormat format; /// Sample rate is the number of frames per second. - /// Defaults to max(sample_rate_min, min(sample_rate_max, 48000)) + /// Defaults to SoundIoDevice::sample_rate_current if available, + /// otherwise 44100 clamped into range. int sample_rate; /// Defaults to Stereo, if available, followed by the first layout diff --git a/src/coreaudio.c b/src/coreaudio.c index f625af0..6106737 100644 --- a/src/coreaudio.c +++ b/src/coreaudio.c @@ -709,29 +709,35 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mScope = aim_to_scope(aim); prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = sizeof(UInt32); - UInt32 buffer_frame_size; if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, - &io_size, &buffer_frame_size))) + &io_size, &dca->buffer_frame_size))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } double use_sample_rate = rd.device->sample_rate_current; - rd.device->software_latency_current = buffer_frame_size / use_sample_rate; + rd.device->software_latency_current = dca->buffer_frame_size / use_sample_rate; + if (aim == SoundIoDeviceAimOutput) { + fprintf(stderr, "buffer_frame_size: %ld\n", (long)dca->buffer_frame_size); + fprintf(stderr, "after dividing by %f, is now %f\n", use_sample_rate, rd.device->software_latency_current); + } prop_address.mSelector = kAudioDevicePropertyBufferFrameSizeRange; prop_address.mScope = aim_to_scope(aim); prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = sizeof(AudioValueRange); - AudioValueRange avr; if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, - &io_size, &avr))) + &io_size, &dca->buffer_frame_size_range))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } - rd.device->software_latency_min = avr.mMinimum / use_sample_rate; - rd.device->software_latency_max = avr.mMaximum / use_sample_rate; + rd.device->software_latency_min = dca->buffer_frame_size_range.mMinimum / use_sample_rate; + rd.device->software_latency_max = dca->buffer_frame_size_range.mMaximum / use_sample_rate; + if (aim == SoundIoDeviceAimOutput) { + fprintf(stderr, "min: %ld max %ld\n", (long)dca->buffer_frame_size_range.mMinimum, + (long)dca->buffer_frame_size_range.mMaximum); + } prop_address.mSelector = kAudioDevicePropertyLatency; prop_address.mScope = aim_to_scope(aim); @@ -921,8 +927,10 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; struct SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; - if (outstream->software_latency == 0.0) - outstream->software_latency = device->software_latency_current; + if (outstream->software_latency == 0.0) { + outstream->software_latency = dca->buffer_frame_size / (double)outstream->sample_rate; + fprintf(stderr, "software_latency default to: %f\n", outstream->software_latency); + } outstream->software_latency = soundio_double_clamp( device->software_latency_min, @@ -989,6 +997,11 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP OUTPUT_ELEMENT }; UInt32 buffer_frame_size = outstream->software_latency * outstream->sample_rate; + buffer_frame_size = clamp((UInt32)dca->buffer_frame_size_range.mMinimum, buffer_frame_size, + (UInt32)dca->buffer_frame_size_range.mMaximum); + + fprintf(stderr, "open buffer_frame_size: %ld after multiplying %f by %d\n", + (long)buffer_frame_size, outstream->software_latency, outstream->sample_rate); if ((os_err = AudioObjectSetPropertyData(dca->device_id, &prop_address, 0, NULL, sizeof(UInt32), &buffer_frame_size))) { diff --git a/src/coreaudio.h b/src/coreaudio.h index a919f0e..b509f72 100644 --- a/src/coreaudio.h +++ b/src/coreaudio.h @@ -22,6 +22,8 @@ int soundio_coreaudio_init(struct SoundIoPrivate *si); struct SoundIoDeviceCoreAudio { AudioDeviceID device_id; UInt32 latency_frames; + AudioValueRange buffer_frame_size_range; + UInt32 buffer_frame_size; }; SOUNDIO_MAKE_LIST_STRUCT(AudioDeviceID, SoundIoListAudioDeviceID, SOUNDIO_LIST_STATIC) diff --git a/src/soundio.c b/src/soundio.c index e01b78e..bf627cf 100644 --- a/src/soundio.c +++ b/src/soundio.c @@ -499,8 +499,10 @@ int soundio_outstream_open(struct SoundIoOutStream *outstream) { outstream->layout = soundio_device_supports_layout(device, stereo) ? *stereo : device->layouts[0]; } - if (!outstream->sample_rate) - outstream->sample_rate = soundio_device_nearest_sample_rate(device, 48000); + if (!outstream->sample_rate) { + outstream->sample_rate = device->sample_rate_current ? device->sample_rate_current : + soundio_device_nearest_sample_rate(device, 44100); + } struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; outstream->bytes_per_frame = soundio_get_bytes_per_frame(outstream->format, outstream->layout.channel_count); @@ -602,8 +604,10 @@ int soundio_instream_open(struct SoundIoInStream *instream) { instream->layout = soundio_device_supports_layout(device, stereo) ? *stereo : device->layouts[0]; } - if (!instream->sample_rate) - instream->sample_rate = soundio_device_nearest_sample_rate(device, 48000); + if (!instream->sample_rate) { + instream->sample_rate = device->sample_rate_current ? device->sample_rate_current : + soundio_device_nearest_sample_rate(device, 44100); + } instream->bytes_per_frame = soundio_get_bytes_per_frame(instream->format, instream->layout.channel_count);