From fd6809f98a546c2abe87b378bb1fe0bbec40a4ef Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 5 May 2015 21:46:17 +0200 Subject: ao_coreaudio_utils: refine format selection Instead of always picking a somehow better format over the previous one, select a format that is equal to or better the requested format, but is also reasonably close. Drop the mFormatID comparison - checking the sample format handles this already. Make sure to exclude channel counts that can't be used. --- audio/out/ao_coreaudio_utils.c | 44 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'audio/out') diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index 79189380ab..fbb336149d 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -268,36 +268,42 @@ void ca_print_asbd(struct ao *ao, const char *description, talloc_free(format); } +// Return whether new is an improvement over old. Assume a higher value means +// better quality, and we always prefer the value closest to the requested one, +// which is still larger than the requested one. +// Equal values prefer the new one (so ca_asbd_is_better() checks other params). +static bool value_is_better(double req, double old, double new) +{ + if (new >= req) { + return old < req || new <= old; + } else { + return old < req && new >= old; + } +} + // Return whether new is an improvement over old (req is the requested format). bool ca_asbd_is_better(AudioStreamBasicDescription *req, AudioStreamBasicDescription *old, AudioStreamBasicDescription *new) { - if (req->mFormatID != new->mFormatID) + if (new->mChannelsPerFrame > MP_NUM_CHANNELS) return false; + if (old->mChannelsPerFrame > MP_NUM_CHANNELS) + return true; - int mpfmt_req = ca_asbd_to_mp_format(old); + int mpfmt_req = ca_asbd_to_mp_format(req); + int mpfmt_old = ca_asbd_to_mp_format(old); int mpfmt_new = ca_asbd_to_mp_format(new); - if (!mpfmt_new) + if (af_format_conversion_score(mpfmt_req, mpfmt_old) > + af_format_conversion_score(mpfmt_req, mpfmt_new)) return false; - if (mpfmt_req != mpfmt_new) { - int mpfmt_old = ca_asbd_to_mp_format(old); - if (af_format_conversion_score(mpfmt_req, mpfmt_old) > - af_format_conversion_score(mpfmt_req, mpfmt_new)) - return false; - } - - if (req->mSampleRate != new->mSampleRate) { - if (old->mSampleRate > new->mSampleRate) - return false; - } + if (!value_is_better(req->mSampleRate, old->mSampleRate, new->mSampleRate)) + return false; - if (req->mChannelsPerFrame != new->mChannelsPerFrame) { - if (old->mChannelsPerFrame > new->mChannelsPerFrame || - new->mChannelsPerFrame > MP_NUM_CHANNELS) - return false; - } + if (!value_is_better(req->mChannelsPerFrame, old->mChannelsPerFrame, + new->mChannelsPerFrame)) + return false; return true; } -- cgit v1.2.3