From af6a24bac9f066eb781a1ed91bdb6b68377ad474 Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Wed, 11 Oct 2017 11:14:14 -0700 Subject: [PATCH] Fix issue with 16-bit PCM on 16-bit builds. Apparently I wrote that code forgetting that the resample type is 32-bit wide, with a 16-bit shift, and the type is signed. This prevented WAV files with a sample rate 32768Hz or higher from playing on 16-bit DOS builds. --- media/dosamp/dosamp.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/media/dosamp/dosamp.c b/media/dosamp/dosamp.c index 09e4e1242..72a782108 100644 --- a/media/dosamp/dosamp.c +++ b/media/dosamp/dosamp.c @@ -1728,12 +1728,18 @@ int negotiate_play_format(struct wav_cbr_t * const d,const struct wav_cbr_t * co d->bytes_per_block = ((d->bits_per_sample+7U)/8U) * d->number_of_channels; { - resample_intermediate_t tmp; - - tmp = (resample_intermediate_t)s->sample_rate << (resample_intermediate_t)resample_100_shift; - tmp /= (resample_intermediate_t)d->sample_rate; - - resample_step = tmp; + /* NTS: Always compute with uint64_t even on 16-bit builds. + * This gives us the precision we need to compute the resample step value. + * Also remember that on 16-bit builds the resample intermediate type is + * 32 bits wide, and the shift is 16. As signed integers, that means that + * this code will produce the wrong value when sample rates >= 32768Hz are + * involved unless we do the math in 64-bit wide integers. */ + uint64_t tmp; + + tmp = (uint64_t)s->sample_rate << (uint64_t)resample_100_shift; + tmp /= (uint64_t)d->sample_rate; + + resample_step = (resample_intermediate_t)tmp; resample_frac = 0; }