From 5dede763fff06ea0c4084bd636607bb786696a0a Mon Sep 17 00:00:00 2001 From: Olli Date: Sun, 23 Feb 2025 12:54:41 +0200 Subject: [PATCH] Refactor pow() usage Refactor pow() usage: - use base of 0.5^k instead of 1/(2^k) - skip pow if using INTEGER_SAMPLES --- source/SoundTouch/BPMDetect.cpp | 2 +- source/SoundTouch/FIRFilter.cpp | 17 ++++++++--------- source/SoundTouch/FIRFilter.h | 3 --- source/SoundTouch/sse_optimized.cpp | 11 ++++------- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/source/SoundTouch/BPMDetect.cpp b/source/SoundTouch/BPMDetect.cpp index f7995c8..43763f7 100644 --- a/source/SoundTouch/BPMDetect.cpp +++ b/source/SoundTouch/BPMDetect.cpp @@ -301,7 +301,7 @@ void BPMDetect::updateXCorr(int process_samples) pBuffer = buffer->ptrBegin(); // calculate decay factor for xcorr filtering - float xcorr_decay = (float)pow(0.5, 1.0 / (XCORR_DECAY_TIME_CONSTANT * TARGET_SRATE / process_samples)); + float xcorr_decay = (float)pow(0.5, process_samples / (XCORR_DECAY_TIME_CONSTANT * TARGET_SRATE)); // prescale pbuffer float tmp[XCORR_UPDATE_SEQUENCE]; diff --git a/source/SoundTouch/FIRFilter.cpp b/source/SoundTouch/FIRFilter.cpp index 20f9311..c8cac30 100644 --- a/source/SoundTouch/FIRFilter.cpp +++ b/source/SoundTouch/FIRFilter.cpp @@ -56,7 +56,6 @@ using namespace soundtouch; FIRFilter::FIRFilter() { resultDivFactor = 0; - resultDivider = 0; length = 0; lengthDiv8 = 0; filterCoeffs = nullptr; @@ -207,24 +206,24 @@ void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint u assert(newLength > 0); if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8"); - #ifdef SOUNDTOUCH_FLOAT_SAMPLES - // scale coefficients already here if using floating samples - double scale = 1.0 / resultDivider; - #else - short scale = 1; - #endif - lengthDiv8 = newLength / 8; length = lengthDiv8 * 8; assert(length == newLength); resultDivFactor = uResultDivFactor; - resultDivider = (SAMPLETYPE)::pow(2.0, (int)resultDivFactor); delete[] filterCoeffs; filterCoeffs = new SAMPLETYPE[length]; delete[] filterCoeffsStereo; filterCoeffsStereo = new SAMPLETYPE[length*2]; + +#ifdef SOUNDTOUCH_FLOAT_SAMPLES + // scale coefficients already here if using floating samples + const double scale = ::pow(0.5, (int)resultDivFactor);; +#else + const short scale = 1; +#endif + for (uint i = 0; i < length; i ++) { filterCoeffs[i] = (SAMPLETYPE)(coeffs[i] * scale); diff --git a/source/SoundTouch/FIRFilter.h b/source/SoundTouch/FIRFilter.h index 0acb199..0ae5083 100644 --- a/source/SoundTouch/FIRFilter.h +++ b/source/SoundTouch/FIRFilter.h @@ -52,9 +52,6 @@ protected: // Result divider factor in 2^k format uint resultDivFactor; - // Result divider value. - SAMPLETYPE resultDivider; - // Memory for filter coefficients SAMPLETYPE *filterCoeffs; SAMPLETYPE *filterCoeffsStereo; diff --git a/source/SoundTouch/sse_optimized.cpp b/source/SoundTouch/sse_optimized.cpp index 73658a5..f3511bc 100644 --- a/source/SoundTouch/sse_optimized.cpp +++ b/source/SoundTouch/sse_optimized.cpp @@ -211,9 +211,6 @@ FIRFilterSSE::~FIRFilterSSE() // (overloaded) Calculates filter coefficients for SSE routine void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor) { - uint i; - float fDivider; - FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor); // Scale the filter coefficients so that it won't be necessary to scale the filtering result @@ -223,13 +220,13 @@ void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uRe filterCoeffsUnalign = new float[2 * newLength + 4]; filterCoeffsAlign = (float *)SOUNDTOUCH_ALIGN_POINTER_16(filterCoeffsUnalign); - fDivider = (float)resultDivider; + const float scale = ::pow(0.5, (int)resultDivFactor); - // rearrange the filter coefficients for mmx routines - for (i = 0; i < newLength; i ++) + // rearrange the filter coefficients for sse routines + for (auto i = 0U; i < newLength; i ++) { filterCoeffsAlign[2 * i + 0] = - filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; + filterCoeffsAlign[2 * i + 1] = coeffs[i] * scale; } }