From c456a2f432724b8a5380486e5bef22e61f7111f8 Mon Sep 17 00:00:00 2001 From: David Reid Date: Sat, 14 Feb 2026 08:54:13 +1000 Subject: [PATCH] Resampler: Experiment with some timer management optimizations. The idea here is to only update the resampler object once at the end. This improves speeds up the problematic s16 mono upsampling path with Clang, but that same path with GCC is still slow somehow. --- miniaudio.h | 340 +++++++++++++++++++++++++++------------------------- 1 file changed, 178 insertions(+), 162 deletions(-) diff --git a/miniaudio.h b/miniaudio.h index 3339a0dd..3d1203d1 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -60323,6 +60323,8 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r ma_uint32 invSampleRateOut; ma_uint32 lpfCount; ma_uint32 channels; + ma_uint32 inTimeInt; + ma_uint32 inTimeFrac; MA_ASSERT(pResampler != NULL); MA_ASSERT(pFramesIn != NULL); @@ -60339,6 +60341,8 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r invSampleRateOut = (1 << MA_LINEAR_RESAMPLER_LERP_SHIFT) / pResampler->sampleRateOut; lpfCount = pResampler->lpfOrder >> 1; channels = pResampler->channels; + inTimeInt = pResampler->inTimeInt; + inTimeFrac = pResampler->inTimeFrac; /* We can run an optimized path when the low-pass filter is not being used. */ if (lpfCount == 0) { @@ -60350,11 +60354,11 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r #if 1 /* If there's a cached frame we need to process it. */ - if (pResampler->inTimeInt == 0) { + if (inTimeInt == 0) { MA_ASSERT(pResampler->cachedFrameCount <= 1); /* There is at most one cached frame. */ while (pResampler->cachedFrameCount > 0 && frameCountIn > 0 && framesProcessedOut < frameCountOut) { - ma_uint32 a = pResampler->inTimeFrac * invSampleRateOut; + ma_uint32 a = inTimeFrac * invSampleRateOut; for (c = 0; c < channels; c += 1) { pFramesOutS16[c] = ma_linear_resampler_mix_s16(pResampler->x0.s16[c], pFramesInS16[c], a); @@ -60366,16 +60370,16 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r framesProcessedOut += 1; /* Advance time forward. */ - pResampler->inTimeInt += pResampler->inAdvanceInt; - pResampler->inTimeFrac += pResampler->inAdvanceFrac; - if (pResampler->inTimeFrac >= pResampler->sampleRateOut) { - pResampler->inTimeFrac -= pResampler->sampleRateOut; - pResampler->inTimeInt += 1; + inTimeInt += pResampler->inAdvanceInt; + inTimeFrac += pResampler->inAdvanceFrac; + if (inTimeFrac >= pResampler->sampleRateOut) { + inTimeFrac -= pResampler->sampleRateOut; + inTimeInt += 1; } /* Subtract one from the time to account for the cached frame, but only if the entire frame was processed. */ - if (pResampler->inTimeInt > 0) { - pResampler->inTimeInt -= 1; + if (inTimeInt > 0) { + inTimeInt -= 1; pResampler->cachedFrameCount = 0; } } @@ -60389,16 +60393,16 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r while (framesProcessedOut + 4 <= frameCountOut) { ma_uint32 inTimeIntTemp; ma_uint32 inTimeFracTemp; - ma_uint32 inTimeInt[4]; - ma_uint32 inTimeFrac[4]; + ma_uint32 inTimeInt4[4]; + ma_uint32 inTimeFrac4[4]; int i; - inTimeIntTemp = pResampler->inTimeInt; - inTimeFracTemp = pResampler->inTimeFrac; + inTimeIntTemp = inTimeInt; + inTimeFracTemp = inTimeFrac; for (i = 0; i < 4; i += 1) { - inTimeInt[i] = inTimeIntTemp; - inTimeFrac[i] = inTimeFracTemp; + inTimeInt4[i] = inTimeIntTemp; + inTimeFrac4[i] = inTimeFracTemp; inTimeIntTemp += pResampler->inAdvanceInt; inTimeFracTemp += pResampler->inAdvanceFrac; @@ -60409,13 +60413,13 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r } /* Check that we have one extra sample at the end for doing the interpolation. */ - if (inTimeInt[3] + 1 >= frameCountIn) { + if (inTimeInt4[3] + 1 >= frameCountIn) { break; /* Not enough input frames. */ } /* Advance the timer. */ - pResampler->inTimeInt = inTimeIntTemp; - pResampler->inTimeFrac = inTimeFracTemp; + inTimeInt = inTimeIntTemp; + inTimeFrac = inTimeFracTemp; /* We should now be able to SIMD-ify the rest. For now I am trusting the compiler to vectorize this, but I'll experiment with some manual stuff later. */ { @@ -60427,20 +60431,20 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r ma_int32 n[4]; ma_int32 r[4]; - x[0] = pFramesInS16[inTimeInt[0] + 0]; - x[1] = pFramesInS16[inTimeInt[1] + 0]; - x[2] = pFramesInS16[inTimeInt[2] + 0]; - x[3] = pFramesInS16[inTimeInt[3] + 0]; + x[0] = pFramesInS16[inTimeInt4[0] + 0]; + x[1] = pFramesInS16[inTimeInt4[1] + 0]; + x[2] = pFramesInS16[inTimeInt4[2] + 0]; + x[3] = pFramesInS16[inTimeInt4[3] + 0]; - y[0] = pFramesInS16[inTimeInt[0] + 1]; - y[1] = pFramesInS16[inTimeInt[1] + 1]; - y[2] = pFramesInS16[inTimeInt[2] + 1]; - y[3] = pFramesInS16[inTimeInt[3] + 1]; + y[0] = pFramesInS16[inTimeInt4[0] + 1]; + y[1] = pFramesInS16[inTimeInt4[1] + 1]; + y[2] = pFramesInS16[inTimeInt4[2] + 1]; + y[3] = pFramesInS16[inTimeInt4[3] + 1]; - a[0] = inTimeFrac[0] * invSampleRateOut; - a[1] = inTimeFrac[1] * invSampleRateOut; - a[2] = inTimeFrac[2] * invSampleRateOut; - a[3] = inTimeFrac[3] * invSampleRateOut; + a[0] = inTimeFrac4[0] * invSampleRateOut; + a[1] = inTimeFrac4[1] * invSampleRateOut; + a[2] = inTimeFrac4[2] * invSampleRateOut; + a[3] = inTimeFrac4[3] * invSampleRateOut; d[0] = y[0] - x[0]; d[1] = y[1] - x[1]; @@ -60471,32 +60475,32 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r ma_int32 n[8]; ma_int32 r[8]; - x[0] = pFramesInS16[((inTimeInt[0] + 0) * 2) + 0]; - x[1] = pFramesInS16[((inTimeInt[0] + 0) * 2) + 1]; - x[2] = pFramesInS16[((inTimeInt[1] + 0) * 2) + 0]; - x[3] = pFramesInS16[((inTimeInt[1] + 0) * 2) + 1]; - x[4] = pFramesInS16[((inTimeInt[2] + 0) * 2) + 0]; - x[5] = pFramesInS16[((inTimeInt[2] + 0) * 2) + 1]; - x[6] = pFramesInS16[((inTimeInt[3] + 0) * 2) + 0]; - x[7] = pFramesInS16[((inTimeInt[3] + 0) * 2) + 1]; + x[0] = pFramesInS16[((inTimeInt4[0] + 0) * 2) + 0]; + x[1] = pFramesInS16[((inTimeInt4[0] + 0) * 2) + 1]; + x[2] = pFramesInS16[((inTimeInt4[1] + 0) * 2) + 0]; + x[3] = pFramesInS16[((inTimeInt4[1] + 0) * 2) + 1]; + x[4] = pFramesInS16[((inTimeInt4[2] + 0) * 2) + 0]; + x[5] = pFramesInS16[((inTimeInt4[2] + 0) * 2) + 1]; + x[6] = pFramesInS16[((inTimeInt4[3] + 0) * 2) + 0]; + x[7] = pFramesInS16[((inTimeInt4[3] + 0) * 2) + 1]; - y[0] = pFramesInS16[((inTimeInt[0] + 1) * 2) + 0]; - y[1] = pFramesInS16[((inTimeInt[0] + 1) * 2) + 1]; - y[2] = pFramesInS16[((inTimeInt[1] + 1) * 2) + 0]; - y[3] = pFramesInS16[((inTimeInt[1] + 1) * 2) + 1]; - y[4] = pFramesInS16[((inTimeInt[2] + 1) * 2) + 0]; - y[5] = pFramesInS16[((inTimeInt[2] + 1) * 2) + 1]; - y[6] = pFramesInS16[((inTimeInt[3] + 1) * 2) + 0]; - y[7] = pFramesInS16[((inTimeInt[3] + 1) * 2) + 1]; + y[0] = pFramesInS16[((inTimeInt4[0] + 1) * 2) + 0]; + y[1] = pFramesInS16[((inTimeInt4[0] + 1) * 2) + 1]; + y[2] = pFramesInS16[((inTimeInt4[1] + 1) * 2) + 0]; + y[3] = pFramesInS16[((inTimeInt4[1] + 1) * 2) + 1]; + y[4] = pFramesInS16[((inTimeInt4[2] + 1) * 2) + 0]; + y[5] = pFramesInS16[((inTimeInt4[2] + 1) * 2) + 1]; + y[6] = pFramesInS16[((inTimeInt4[3] + 1) * 2) + 0]; + y[7] = pFramesInS16[((inTimeInt4[3] + 1) * 2) + 1]; - a[0] = inTimeFrac[0] * invSampleRateOut; - a[1] = inTimeFrac[0] * invSampleRateOut; - a[2] = inTimeFrac[1] * invSampleRateOut; - a[3] = inTimeFrac[1] * invSampleRateOut; - a[4] = inTimeFrac[2] * invSampleRateOut; - a[5] = inTimeFrac[2] * invSampleRateOut; - a[6] = inTimeFrac[3] * invSampleRateOut; - a[7] = inTimeFrac[3] * invSampleRateOut; + a[0] = inTimeFrac4[0] * invSampleRateOut; + a[1] = inTimeFrac4[0] * invSampleRateOut; + a[2] = inTimeFrac4[1] * invSampleRateOut; + a[3] = inTimeFrac4[1] * invSampleRateOut; + a[4] = inTimeFrac4[2] * invSampleRateOut; + a[5] = inTimeFrac4[2] * invSampleRateOut; + a[6] = inTimeFrac4[3] * invSampleRateOut; + a[7] = inTimeFrac4[3] * invSampleRateOut; d[0] = y[0] - x[0]; d[1] = y[1] - x[1]; @@ -60544,20 +60548,20 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r ma_int32 n[4]; ma_int32 r[4]; - x[0] = pFramesInS16[((inTimeInt[0] + 0) * channels) + c]; - x[1] = pFramesInS16[((inTimeInt[1] + 0) * channels) + c]; - x[2] = pFramesInS16[((inTimeInt[2] + 0) * channels) + c]; - x[3] = pFramesInS16[((inTimeInt[3] + 0) * channels) + c]; + x[0] = pFramesInS16[((inTimeInt4[0] + 0) * channels) + c]; + x[1] = pFramesInS16[((inTimeInt4[1] + 0) * channels) + c]; + x[2] = pFramesInS16[((inTimeInt4[2] + 0) * channels) + c]; + x[3] = pFramesInS16[((inTimeInt4[3] + 0) * channels) + c]; - y[0] = pFramesInS16[((inTimeInt[0] + 1) * channels) + c]; - y[1] = pFramesInS16[((inTimeInt[1] + 1) * channels) + c]; - y[2] = pFramesInS16[((inTimeInt[2] + 1) * channels) + c]; - y[3] = pFramesInS16[((inTimeInt[3] + 1) * channels) + c]; + y[0] = pFramesInS16[((inTimeInt4[0] + 1) * channels) + c]; + y[1] = pFramesInS16[((inTimeInt4[1] + 1) * channels) + c]; + y[2] = pFramesInS16[((inTimeInt4[2] + 1) * channels) + c]; + y[3] = pFramesInS16[((inTimeInt4[3] + 1) * channels) + c]; - a[0] = inTimeFrac[0] * invSampleRateOut; - a[1] = inTimeFrac[1] * invSampleRateOut; - a[2] = inTimeFrac[2] * invSampleRateOut; - a[3] = inTimeFrac[3] * invSampleRateOut; + a[0] = inTimeFrac4[0] * invSampleRateOut; + a[1] = inTimeFrac4[1] * invSampleRateOut; + a[2] = inTimeFrac4[2] * invSampleRateOut; + a[3] = inTimeFrac4[3] * invSampleRateOut; d[0] = y[0] - x[0]; d[1] = y[1] - x[1]; @@ -60590,12 +60594,12 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r } #endif - while (framesProcessedOut < frameCountOut && pResampler->inTimeInt < frameCountIn) { - if (pResampler->inTimeInt + 1 < frameCountIn) { - ma_uint32 a = pResampler->inTimeFrac * invSampleRateOut; + while (framesProcessedOut < frameCountOut && inTimeInt < frameCountIn) { + if (inTimeInt + 1 < frameCountIn) { + ma_uint32 a = inTimeFrac * invSampleRateOut; for (c = 0; c < channels; c += 1) { - pFramesOutS16[c] = ma_linear_resampler_mix_s16(pFramesInS16[((pResampler->inTimeInt + 0) * channels) + c], pFramesInS16[((pResampler->inTimeInt + 1) * channels) + c], a); + pFramesOutS16[c] = ma_linear_resampler_mix_s16(pFramesInS16[((inTimeInt + 0) * channels) + c], pFramesInS16[((inTimeInt + 1) * channels) + c], a); } ma_linear_resampler_filter_s16(pLPF, lpfCount, channels, pFramesOutS16); @@ -60604,11 +60608,11 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r framesProcessedOut += 1; /* Advance time forward. */ - pResampler->inTimeInt += pResampler->inAdvanceInt; - pResampler->inTimeFrac += pResampler->inAdvanceFrac; - if (pResampler->inTimeFrac >= pResampler->sampleRateOut) { - pResampler->inTimeFrac -= pResampler->sampleRateOut; - pResampler->inTimeInt += 1; + inTimeInt += pResampler->inAdvanceInt; + inTimeFrac += pResampler->inAdvanceFrac; + if (inTimeFrac >= pResampler->sampleRateOut) { + inTimeFrac -= pResampler->sampleRateOut; + inTimeInt += 1; } } else { /* @@ -60616,26 +60620,26 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r the frame to ensure we make some forward progress. */ for (c = 0; c < channels; c += 1) { - pResampler->x0.s16[c] = pFramesInS16[((pResampler->inTimeInt + 0) * channels) + c]; + pResampler->x0.s16[c] = pFramesInS16[((inTimeInt + 0) * channels) + c]; } pResampler->cachedFrameCount = 1; - pResampler->inTimeInt += 1; + inTimeInt += 1; break; } } /* The number of frames we processed is simply the difference between our current time and previous time, clamped. */ - framesProcessedIn = pResampler->inTimeInt; + framesProcessedIn = inTimeInt; if (framesProcessedIn > frameCountIn) { /* Should never overshoot when upsampling. Downsampling could overshoot. */ framesProcessedIn = frameCountIn; } - if (pResampler->inTimeInt >= framesProcessedIn) { - pResampler->inTimeInt -= framesProcessedIn; + if (inTimeInt >= framesProcessedIn) { + inTimeInt -= framesProcessedIn; } else { - pResampler->inTimeInt = 0; + inTimeInt = 0; } /* @@ -60648,6 +60652,10 @@ static ma_result ma_linear_resampler_process_pcm_frames_s16_upsample(ma_linear_r } } + /* Don't forget to update the time. */ + pResampler->inTimeInt = inTimeInt; + pResampler->inTimeFrac = inTimeFrac; + *pFrameCountIn = framesProcessedIn; *pFrameCountOut = framesProcessedOut; @@ -60808,6 +60816,8 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r double invSampleRateOut; ma_uint32 lpfCount; ma_uint32 channels; + ma_uint32 inTimeInt; + ma_uint32 inTimeFrac; MA_ASSERT(pResampler != NULL); MA_ASSERT(pFrameCountIn != NULL); @@ -60822,6 +60832,8 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r invSampleRateOut = (1.0 / pResampler->sampleRateOut); lpfCount = pResampler->lpfOrder >> 1; channels = pResampler->channels; + inTimeInt = pResampler->inTimeInt; + inTimeFrac = pResampler->inTimeFrac; if (lpfCount == 0) { /* Fast path. No LPF needed. */ @@ -60834,11 +60846,11 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r #if 1 /* If there's a cached frame we need to process it. */ - if (pResampler->inTimeInt == 0) { + if (inTimeInt == 0) { MA_ASSERT(pResampler->cachedFrameCount <= 1); /* There is at most one cached frame. */ while (pResampler->cachedFrameCount > 0 && frameCountIn > 0 && framesProcessedOut < frameCountOut) { - float a = (float)(pResampler->inTimeFrac * invSampleRateOut); + float a = (float)(inTimeFrac * invSampleRateOut); for (c = 0; c < channels; c += 1) { pFramesOutF32[c] = ma_mix_f32_fast(pResampler->x0.f32[c], pFramesInF32[c], a); @@ -60850,16 +60862,16 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r framesProcessedOut += 1; /* Advance time forward. */ - pResampler->inTimeInt += pResampler->inAdvanceInt; - pResampler->inTimeFrac += pResampler->inAdvanceFrac; - if (pResampler->inTimeFrac >= pResampler->sampleRateOut) { - pResampler->inTimeFrac -= pResampler->sampleRateOut; - pResampler->inTimeInt += 1; + inTimeInt += pResampler->inAdvanceInt; + inTimeFrac += pResampler->inAdvanceFrac; + if (inTimeFrac >= pResampler->sampleRateOut) { + inTimeFrac -= pResampler->sampleRateOut; + inTimeInt += 1; } /* Subtract one from the time to account for the cached frame, but only if the entire frame was processed. */ - if (pResampler->inTimeInt > 0) { - pResampler->inTimeInt -= 1; + if (inTimeInt > 0) { + inTimeInt -= 1; pResampler->cachedFrameCount = 0; } } @@ -60873,16 +60885,16 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r while (framesProcessedOut + 4 <= frameCountOut) { ma_uint32 inTimeIntTemp; ma_uint32 inTimeFracTemp; - ma_uint32 inTimeInt[4]; - ma_uint32 inTimeFrac[4]; + ma_uint32 inTimeInt4[4]; + ma_uint32 inTimeFrac4[4]; int i; - inTimeIntTemp = pResampler->inTimeInt; - inTimeFracTemp = pResampler->inTimeFrac; + inTimeIntTemp = inTimeInt; + inTimeFracTemp = inTimeFrac; for (i = 0; i < 4; i += 1) { - inTimeInt[i] = inTimeIntTemp; - inTimeFrac[i] = inTimeFracTemp; + inTimeInt4[i] = inTimeIntTemp; + inTimeFrac4[i] = inTimeFracTemp; inTimeIntTemp += pResampler->inAdvanceInt; inTimeFracTemp += pResampler->inAdvanceFrac; @@ -60893,13 +60905,13 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r } /* Check that we have one extra sample at the end for doing the interpolation. */ - if (inTimeInt[3] + 1 >= frameCountIn) { + if (inTimeInt4[3] + 1 >= frameCountIn) { break; /* Not enough input frames. */ } /* Advance the timer. */ - pResampler->inTimeInt = inTimeIntTemp; - pResampler->inTimeFrac = inTimeFracTemp; + inTimeInt = inTimeIntTemp; + inTimeFrac = inTimeFracTemp; /* We should now be able to SIMD-ify the rest. For now I am trusting the compiler to vectorize this, but I'll experiment with some manual stuff later. */ { @@ -60911,20 +60923,20 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r float n[4]; float r[4]; - x[0] = pFramesInF32[inTimeInt[0] + 0]; - x[1] = pFramesInF32[inTimeInt[1] + 0]; - x[2] = pFramesInF32[inTimeInt[2] + 0]; - x[3] = pFramesInF32[inTimeInt[3] + 0]; + x[0] = pFramesInF32[inTimeInt4[0] + 0]; + x[1] = pFramesInF32[inTimeInt4[1] + 0]; + x[2] = pFramesInF32[inTimeInt4[2] + 0]; + x[3] = pFramesInF32[inTimeInt4[3] + 0]; - y[0] = pFramesInF32[inTimeInt[0] + 1]; - y[1] = pFramesInF32[inTimeInt[1] + 1]; - y[2] = pFramesInF32[inTimeInt[2] + 1]; - y[3] = pFramesInF32[inTimeInt[3] + 1]; + y[0] = pFramesInF32[inTimeInt4[0] + 1]; + y[1] = pFramesInF32[inTimeInt4[1] + 1]; + y[2] = pFramesInF32[inTimeInt4[2] + 1]; + y[3] = pFramesInF32[inTimeInt4[3] + 1]; - a[0] = inTimeFrac[0] * invSampleRateOut; - a[1] = inTimeFrac[1] * invSampleRateOut; - a[2] = inTimeFrac[2] * invSampleRateOut; - a[3] = inTimeFrac[3] * invSampleRateOut; + a[0] = inTimeFrac4[0] * invSampleRateOut; + a[1] = inTimeFrac4[1] * invSampleRateOut; + a[2] = inTimeFrac4[2] * invSampleRateOut; + a[3] = inTimeFrac4[3] * invSampleRateOut; d[0] = y[0] - x[0]; d[1] = y[1] - x[1]; @@ -60955,32 +60967,32 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r float n[8]; float r[8]; - x[0] = pFramesInF32[((inTimeInt[0] + 0) * 2) + 0]; - x[1] = pFramesInF32[((inTimeInt[0] + 0) * 2) + 1]; - x[2] = pFramesInF32[((inTimeInt[1] + 0) * 2) + 0]; - x[3] = pFramesInF32[((inTimeInt[1] + 0) * 2) + 1]; - x[4] = pFramesInF32[((inTimeInt[2] + 0) * 2) + 0]; - x[5] = pFramesInF32[((inTimeInt[2] + 0) * 2) + 1]; - x[6] = pFramesInF32[((inTimeInt[3] + 0) * 2) + 0]; - x[7] = pFramesInF32[((inTimeInt[3] + 0) * 2) + 1]; + x[0] = pFramesInF32[((inTimeInt4[0] + 0) * 2) + 0]; + x[1] = pFramesInF32[((inTimeInt4[0] + 0) * 2) + 1]; + x[2] = pFramesInF32[((inTimeInt4[1] + 0) * 2) + 0]; + x[3] = pFramesInF32[((inTimeInt4[1] + 0) * 2) + 1]; + x[4] = pFramesInF32[((inTimeInt4[2] + 0) * 2) + 0]; + x[5] = pFramesInF32[((inTimeInt4[2] + 0) * 2) + 1]; + x[6] = pFramesInF32[((inTimeInt4[3] + 0) * 2) + 0]; + x[7] = pFramesInF32[((inTimeInt4[3] + 0) * 2) + 1]; - y[0] = pFramesInF32[((inTimeInt[0] + 1) * 2) + 0]; - y[1] = pFramesInF32[((inTimeInt[0] + 1) * 2) + 1]; - y[2] = pFramesInF32[((inTimeInt[1] + 1) * 2) + 0]; - y[3] = pFramesInF32[((inTimeInt[1] + 1) * 2) + 1]; - y[4] = pFramesInF32[((inTimeInt[2] + 1) * 2) + 0]; - y[5] = pFramesInF32[((inTimeInt[2] + 1) * 2) + 1]; - y[6] = pFramesInF32[((inTimeInt[3] + 1) * 2) + 0]; - y[7] = pFramesInF32[((inTimeInt[3] + 1) * 2) + 1]; + y[0] = pFramesInF32[((inTimeInt4[0] + 1) * 2) + 0]; + y[1] = pFramesInF32[((inTimeInt4[0] + 1) * 2) + 1]; + y[2] = pFramesInF32[((inTimeInt4[1] + 1) * 2) + 0]; + y[3] = pFramesInF32[((inTimeInt4[1] + 1) * 2) + 1]; + y[4] = pFramesInF32[((inTimeInt4[2] + 1) * 2) + 0]; + y[5] = pFramesInF32[((inTimeInt4[2] + 1) * 2) + 1]; + y[6] = pFramesInF32[((inTimeInt4[3] + 1) * 2) + 0]; + y[7] = pFramesInF32[((inTimeInt4[3] + 1) * 2) + 1]; - a[0] = inTimeFrac[0] * invSampleRateOut; - a[1] = inTimeFrac[0] * invSampleRateOut; - a[2] = inTimeFrac[1] * invSampleRateOut; - a[3] = inTimeFrac[1] * invSampleRateOut; - a[4] = inTimeFrac[2] * invSampleRateOut; - a[5] = inTimeFrac[2] * invSampleRateOut; - a[6] = inTimeFrac[3] * invSampleRateOut; - a[7] = inTimeFrac[3] * invSampleRateOut; + a[0] = inTimeFrac4[0] * invSampleRateOut; + a[1] = inTimeFrac4[0] * invSampleRateOut; + a[2] = inTimeFrac4[1] * invSampleRateOut; + a[3] = inTimeFrac4[1] * invSampleRateOut; + a[4] = inTimeFrac4[2] * invSampleRateOut; + a[5] = inTimeFrac4[2] * invSampleRateOut; + a[6] = inTimeFrac4[3] * invSampleRateOut; + a[7] = inTimeFrac4[3] * invSampleRateOut; d[0] = y[0] - x[0]; d[1] = y[1] - x[1]; @@ -61028,20 +61040,20 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r float n[4]; float r[4]; - x[0] = pFramesInF32[((inTimeInt[0] + 0) * channels) + c]; - x[1] = pFramesInF32[((inTimeInt[1] + 0) * channels) + c]; - x[2] = pFramesInF32[((inTimeInt[2] + 0) * channels) + c]; - x[3] = pFramesInF32[((inTimeInt[3] + 0) * channels) + c]; + x[0] = pFramesInF32[((inTimeInt4[0] + 0) * channels) + c]; + x[1] = pFramesInF32[((inTimeInt4[1] + 0) * channels) + c]; + x[2] = pFramesInF32[((inTimeInt4[2] + 0) * channels) + c]; + x[3] = pFramesInF32[((inTimeInt4[3] + 0) * channels) + c]; - y[0] = pFramesInF32[((inTimeInt[0] + 1) * channels) + c]; - y[1] = pFramesInF32[((inTimeInt[1] + 1) * channels) + c]; - y[2] = pFramesInF32[((inTimeInt[2] + 1) * channels) + c]; - y[3] = pFramesInF32[((inTimeInt[3] + 1) * channels) + c]; + y[0] = pFramesInF32[((inTimeInt4[0] + 1) * channels) + c]; + y[1] = pFramesInF32[((inTimeInt4[1] + 1) * channels) + c]; + y[2] = pFramesInF32[((inTimeInt4[2] + 1) * channels) + c]; + y[3] = pFramesInF32[((inTimeInt4[3] + 1) * channels) + c]; - a[0] = inTimeFrac[0] * invSampleRateOut; - a[1] = inTimeFrac[1] * invSampleRateOut; - a[2] = inTimeFrac[2] * invSampleRateOut; - a[3] = inTimeFrac[3] * invSampleRateOut; + a[0] = inTimeFrac4[0] * invSampleRateOut; + a[1] = inTimeFrac4[1] * invSampleRateOut; + a[2] = inTimeFrac4[2] * invSampleRateOut; + a[3] = inTimeFrac4[3] * invSampleRateOut; d[0] = y[0] - x[0]; d[1] = y[1] - x[1]; @@ -61074,12 +61086,12 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r } #endif - while (framesProcessedOut < frameCountOut && pResampler->inTimeInt < frameCountIn) { - if (pResampler->inTimeInt + 1 < frameCountIn) { - float a = (float)(pResampler->inTimeFrac * invSampleRateOut); + while (framesProcessedOut < frameCountOut && inTimeInt < frameCountIn) { + if (inTimeInt + 1 < frameCountIn) { + float a = (float)(inTimeFrac * invSampleRateOut); for (c = 0; c < channels; c += 1) { - pFramesOutF32[c] = ma_mix_f32_fast(pFramesInF32[((pResampler->inTimeInt + 0) * channels) + c], pFramesInF32[((pResampler->inTimeInt + 1) * channels) + c], a); + pFramesOutF32[c] = ma_mix_f32_fast(pFramesInF32[((inTimeInt + 0) * channels) + c], pFramesInF32[((inTimeInt + 1) * channels) + c], a); } ma_linear_resampler_filter_f32(pLPF, lpfCount, channels, pFramesOutF32); @@ -61088,11 +61100,11 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r framesProcessedOut += 1; /* Advance time forward. */ - pResampler->inTimeInt += pResampler->inAdvanceInt; - pResampler->inTimeFrac += pResampler->inAdvanceFrac; - if (pResampler->inTimeFrac >= pResampler->sampleRateOut) { - pResampler->inTimeFrac -= pResampler->sampleRateOut; - pResampler->inTimeInt += 1; + inTimeInt += pResampler->inAdvanceInt; + inTimeFrac += pResampler->inAdvanceFrac; + if (inTimeFrac >= pResampler->sampleRateOut) { + inTimeFrac -= pResampler->sampleRateOut; + inTimeInt += 1; } } else { /* @@ -61100,26 +61112,26 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r the frame to ensure we make some forward progress. */ for (c = 0; c < channels; c += 1) { - pResampler->x0.f32[c] = pFramesInF32[((pResampler->inTimeInt + 0) * channels) + c]; + pResampler->x0.f32[c] = pFramesInF32[((inTimeInt + 0) * channels) + c]; } pResampler->cachedFrameCount = 1; - pResampler->inTimeInt += 1; + inTimeInt += 1; break; } } /* The number of frames we processed is simply the difference between our current time and previous time, clamped. */ - framesProcessedIn = pResampler->inTimeInt; + framesProcessedIn = inTimeInt; if (framesProcessedIn > frameCountIn) { /* Should never overshoot when upsampling. Downsampling could overshoot. */ framesProcessedIn = frameCountIn; } - if (pResampler->inTimeInt >= framesProcessedIn) { - pResampler->inTimeInt -= framesProcessedIn; + if (inTimeInt >= framesProcessedIn) { + inTimeInt -= framesProcessedIn; } else { - pResampler->inTimeInt = 0; + inTimeInt = 0; } /* @@ -61132,6 +61144,10 @@ static ma_result ma_linear_resampler_process_pcm_frames_f32_upsample(ma_linear_r } } + /* Don't forget to update the time. */ + pResampler->inTimeInt = inTimeInt; + pResampler->inTimeFrac = inTimeFrac; + *pFrameCountIn = framesProcessedIn; *pFrameCountOut = framesProcessedOut;