audiounit: Resample to match output device hardware sample rate in uncommon cases.

In some cases, weird sample rates can cause AudioUnit output
units to misbehave. Instead, use resampling for non-native rates
to make sure this does not happen.
This commit is contained in:
Steveice10 2023-12-22 10:49:41 -08:00 коммит произвёл Paul Adenot
Родитель dd8a91f982
Коммит d0ffc6d302
1 изменённых файлов: 22 добавлений и 3 удалений

Просмотреть файл

@ -377,6 +377,14 @@ cubeb_channel_to_channel_label(cubeb_channel channel)
}
}
bool is_common_sample_rate(Float64 sample_rate)
{
/* Some commonly used sample rates and their multiples and divisors. */
return sample_rate == 8000 || sample_rate == 16000 || sample_rate == 22050 ||
sample_rate == 32000 || sample_rate == 44100 || sample_rate == 48000 ||
sample_rate == 88200 || sample_rate == 96000;
}
#if TARGET_OS_IPHONE
typedef UInt32 AudioDeviceID;
typedef UInt32 AudioObjectID;
@ -2502,6 +2510,12 @@ audiounit_configure_output(cubeb_stream * stm)
return CUBEB_ERROR;
}
stm->output_hw_rate = output_hw_desc.mSampleRate;
if (!is_common_sample_rate(stm->output_desc.mSampleRate)) {
/* For uncommon sample rates, we may run into issues with the OS
resampler if we don't do the resampling ourselves, so set the
AudioUnit sample rate to the hardware rate and resample. */
stm->output_desc.mSampleRate = stm->output_hw_rate;
}
LOG("(%p) Output device sampling rate: %.2f", stm,
output_hw_desc.mSampleRate);
stm->context->channels = output_hw_desc.mChannelsPerFrame;
@ -2709,11 +2723,16 @@ audiounit_setup_stream(cubeb_stream * stm)
input_unconverted_params.rate = stm->input_hw_rate;
}
/* Create resampler. Output params are unchanged
* because we do not need conversion on the output. */
cubeb_stream_params output_unconverted_params;
if (has_output(stm)) {
output_unconverted_params = stm->output_stream_params;
output_unconverted_params.rate = stm->output_desc.mSampleRate;
}
/* Create resampler. */
stm->resampler.reset(cubeb_resampler_create(
stm, has_input(stm) ? &input_unconverted_params : NULL,
has_output(stm) ? &stm->output_stream_params : NULL, target_sample_rate,
has_output(stm) ? &output_unconverted_params : NULL, target_sample_rate,
stm->data_callback, stm->user_ptr, CUBEB_RESAMPLER_QUALITY_DESKTOP,
CUBEB_RESAMPLER_RECLOCK_NONE));
if (!stm->resampler) {