diff --git a/modules/juce_dsp/filter_design/juce_FilterDesign.cpp b/modules/juce_dsp/filter_design/juce_FilterDesign.cpp index e250f53402..8327c91585 100644 --- a/modules/juce_dsp/filter_design/juce_FilterDesign.cpp +++ b/modules/juce_dsp/filter_design/juce_FilterDesign.cpp @@ -42,18 +42,18 @@ typename FIR::Coefficients::Ptr auto* result = new typename FIR::Coefficients (order + 1u); auto* c = result->getRawCoefficients(); - auto normalizedFrequency = frequency / sampleRate; + auto normalisedFrequency = frequency / sampleRate; for (size_t i = 0; i <= order; ++i) { if (i == order * 0.5) { - c[i] = static_cast (normalizedFrequency * 2); + c[i] = static_cast (normalisedFrequency * 2); } else { auto indice = MathConstants::pi * (static_cast (i) - 0.5 * static_cast (order)); - c[i] = static_cast (std::sin (2.0 * indice * normalizedFrequency) / indice); + c[i] = static_cast (std::sin (2.0 * indice * normalisedFrequency) / indice); } } @@ -66,23 +66,23 @@ typename FIR::Coefficients::Ptr template typename FIR::Coefficients::Ptr FilterDesign::designFIRLowpassKaiserMethod (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType attenuationdB) + FloatType normalisedTransitionWidth, + FloatType amplitudedB) { jassert (sampleRate > 0); jassert (frequency > 0 && frequency <= sampleRate * 0.5); - jassert (normalizedTransitionWidth > 0 && normalizedTransitionWidth <= 0.5); - jassert (attenuationdB >= -100 && attenuationdB <= 0); + jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5); + jassert (amplitudedB >= -100 && amplitudedB <= 0); FloatType beta = 0; - if (attenuationdB < -50) - beta = static_cast (0.1102 * (-attenuationdB - 8.7)); - else if (attenuationdB <= 21) - beta = static_cast (0.5842 * std::pow (-attenuationdB - 21, 0.4) + 0.07886 * (-attenuationdB - 21)); + if (amplitudedB < -50) + beta = static_cast (0.1102 * (-amplitudedB - 8.7)); + else if (amplitudedB <= 21) + beta = static_cast (0.5842 * std::pow (-amplitudedB - 21, 0.4) + 0.07886 * (-amplitudedB - 21)); - int order = attenuationdB < -21 ? roundToInt (std::ceil ((-attenuationdB - 7.95) / (2.285 * normalizedTransitionWidth * MathConstants::twoPi))) - : roundToInt (std::ceil (5.79 / (normalizedTransitionWidth * MathConstants::twoPi))); + int order = amplitudedB < -21 ? roundToInt (std::ceil ((-amplitudedB - 7.95) / (2.285 * normalisedTransitionWidth * MathConstants::twoPi))) + : roundToInt (std::ceil (5.79 / (normalisedTransitionWidth * MathConstants::twoPi))); jassert (order >= 0); @@ -94,14 +94,14 @@ typename FIR::Coefficients::Ptr template typename FIR::Coefficients::Ptr FilterDesign::designFIRLowpassTransitionMethod (FloatType frequency, double sampleRate, size_t order, - FloatType normalizedTransitionWidth, FloatType spline) + FloatType normalisedTransitionWidth, FloatType spline) { jassert (sampleRate > 0); jassert (frequency > 0 && frequency <= sampleRate * 0.5); - jassert (normalizedTransitionWidth > 0 && normalizedTransitionWidth <= 0.5); + jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5); jassert (spline >= 1.0 && spline <= 4.0); - auto normalizedFrequency = frequency / static_cast (sampleRate); + auto normalisedFrequency = frequency / static_cast (sampleRate); auto* result = new typename FIR::Coefficients (order + 1u); auto* c = result->getRawCoefficients(); @@ -110,13 +110,13 @@ typename FIR::Coefficients::Ptr { if (i == order / 2 && order % 2 == 0) { - c[i] = static_cast (2 * normalizedFrequency); + c[i] = static_cast (2 * normalisedFrequency); } else { auto indice = MathConstants::pi * (i - 0.5 * order); - auto indice2 = MathConstants::pi * normalizedTransitionWidth * (i - 0.5 * order) / spline; - c[i] = static_cast (std::sin (2 * indice * normalizedFrequency) + auto indice2 = MathConstants::pi * normalisedTransitionWidth * (i - 0.5 * order) / spline; + c[i] = static_cast (std::sin (2 * indice * normalisedFrequency) / indice * std::pow (std::sin (indice2) / indice2, spline)); } } @@ -128,18 +128,18 @@ template typename FIR::Coefficients::Ptr FilterDesign::designFIRLowpassLeastSquaresMethod (FloatType frequency, double sampleRate, size_t order, - FloatType normalizedTransitionWidth, + FloatType normalisedTransitionWidth, FloatType stopBandWeight) { jassert (sampleRate > 0); jassert (frequency > 0 && frequency <= sampleRate * 0.5); - jassert (normalizedTransitionWidth > 0 && normalizedTransitionWidth <= 0.5); + jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5); jassert (stopBandWeight >= 1.0 && stopBandWeight <= 100.0); - auto normalizedFrequency = static_cast (frequency) / sampleRate; + auto normalisedFrequency = static_cast (frequency) / sampleRate; - auto wp = MathConstants::twoPi * (static_cast (normalizedFrequency - normalizedTransitionWidth / 2.0)); - auto ws = MathConstants::twoPi * (static_cast (normalizedFrequency + normalizedTransitionWidth / 2.0)); + auto wp = MathConstants::twoPi * (static_cast (normalisedFrequency - normalisedTransitionWidth / 2.0)); + auto ws = MathConstants::twoPi * (static_cast (normalisedFrequency + normalisedTransitionWidth / 2.0)); auto N = order + 1; @@ -236,15 +236,15 @@ typename FIR::Coefficients::Ptr template typename FIR::Coefficients::Ptr - FilterDesign::designFIRLowpassHalfBandEquirippleMethod (FloatType normalizedTransitionWidth, - FloatType attenuationdB) + FilterDesign::designFIRLowpassHalfBandEquirippleMethod (FloatType normalisedTransitionWidth, + FloatType amplitudedB) { - jassert (normalizedTransitionWidth > 0 && normalizedTransitionWidth <= 0.5); - jassert (attenuationdB >= -300 && attenuationdB <= -10); + jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5); + jassert (amplitudedB >= -300 && amplitudedB <= -10); - auto wpT = (0.5 - normalizedTransitionWidth) * MathConstants::pi; + auto wpT = (0.5 - normalisedTransitionWidth) * MathConstants::pi; - auto n = roundToInt (std::ceil ((attenuationdB - 18.18840664 * wpT + 33.64775300) / (18.54155181 * wpT - 29.13196871))); + auto n = roundToInt (std::ceil ((amplitudedB - 18.18840664 * wpT + 33.64775300) / (18.54155181 * wpT - 29.13196871))); auto kp = (n * wpT - 1.57111377 * n + 0.00665857) / (-1.01927560 * n + 0.37221484); auto A = (0.01525753 * n + 0.03682344 + 9.24760314 / (double) n) * kp + 1.01701407 + 0.73512298 / (double) n; auto B = (0.00233667 * n - 1.35418408 + 5.75145813 / (double) n) * kp + 1.02999650 - 0.72759508 / (double) n; @@ -339,67 +339,67 @@ Array FilterDesign::getPartialImpulseResponseHn (int n, doubl template ReferenceCountedArray> FilterDesign::designIIRLowpassHighOrderButterworthMethod (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB) + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB) { - return designIIRLowpassHighOrderGeneralMethod (0, frequency, sampleRate, normalizedTransitionWidth, - passbandAttenuationdB, stopbandAttenuationdB); + return designIIRLowpassHighOrderGeneralMethod (0, frequency, sampleRate, normalisedTransitionWidth, + passbandAmplitudedB, stopbandAmplitudedB); } template ReferenceCountedArray> FilterDesign::designIIRLowpassHighOrderChebyshev1Method (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB) + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB) { - return designIIRLowpassHighOrderGeneralMethod (1, frequency, sampleRate, normalizedTransitionWidth, - passbandAttenuationdB, stopbandAttenuationdB); + return designIIRLowpassHighOrderGeneralMethod (1, frequency, sampleRate, normalisedTransitionWidth, + passbandAmplitudedB, stopbandAmplitudedB); } template ReferenceCountedArray> FilterDesign::designIIRLowpassHighOrderChebyshev2Method (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB) + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB) { - return designIIRLowpassHighOrderGeneralMethod (2, frequency, sampleRate, normalizedTransitionWidth, - passbandAttenuationdB, stopbandAttenuationdB); + return designIIRLowpassHighOrderGeneralMethod (2, frequency, sampleRate, normalisedTransitionWidth, + passbandAmplitudedB, stopbandAmplitudedB); } template ReferenceCountedArray> FilterDesign::designIIRLowpassHighOrderEllipticMethod (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB) + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB) { - return designIIRLowpassHighOrderGeneralMethod (3, frequency, sampleRate, normalizedTransitionWidth, - passbandAttenuationdB, stopbandAttenuationdB); + return designIIRLowpassHighOrderGeneralMethod (3, frequency, sampleRate, normalisedTransitionWidth, + passbandAmplitudedB, stopbandAmplitudedB); } template ReferenceCountedArray> FilterDesign::designIIRLowpassHighOrderGeneralMethod (int type, FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB) + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB) { jassert (sampleRate > 0); jassert (frequency > 0 && frequency <= sampleRate * 0.5); - jassert (normalizedTransitionWidth > 0 && normalizedTransitionWidth <= 0.5); - jassert (passbandAttenuationdB > -20 && passbandAttenuationdB < 0); - jassert (stopbandAttenuationdB > -300 && stopbandAttenuationdB < -20); + jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5); + jassert (passbandAmplitudedB > -20 && passbandAmplitudedB < 0); + jassert (stopbandAmplitudedB > -300 && stopbandAmplitudedB < -20); - auto normalizedFrequency = frequency / sampleRate; + auto normalisedFrequency = frequency / sampleRate; - auto fp = normalizedFrequency - normalizedTransitionWidth / 2; - auto fs = normalizedFrequency + normalizedTransitionWidth / 2; + auto fp = normalisedFrequency - normalisedTransitionWidth / 2; + auto fs = normalisedFrequency + normalisedTransitionWidth / 2; - double Ap = passbandAttenuationdB; - double As = stopbandAttenuationdB; + double Ap = passbandAmplitudedB; + double As = stopbandAmplitudedB; auto Gp = Decibels::decibelsToGain (Ap, -300.0); auto Gs = Decibels::decibelsToGain (As, -300.0); auto epsp = std::sqrt (1.0 / (Gp * Gp) - 1.0); @@ -610,14 +610,14 @@ ReferenceCountedArray> template typename FilterDesign::IIRPolyphaseAllpassStructure - FilterDesign::designIIRLowpassHalfBandPolyphaseAllpassMethod (FloatType normalizedTransitionWidth, - FloatType stopbandAttenuationdB) + FilterDesign::designIIRLowpassHalfBandPolyphaseAllpassMethod (FloatType normalisedTransitionWidth, + FloatType stopbandAmplitudedB) { - jassert (normalizedTransitionWidth > 0 && normalizedTransitionWidth <= 0.5); - jassert (stopbandAttenuationdB > -300 && stopbandAttenuationdB < -10); + jassert (normalisedTransitionWidth > 0 && normalisedTransitionWidth <= 0.5); + jassert (stopbandAmplitudedB > -300 && stopbandAmplitudedB < -10); - const double wt = MathConstants::twoPi * normalizedTransitionWidth; - const double ds = Decibels::decibelsToGain (stopbandAttenuationdB, static_cast (-300.0)); + const double wt = MathConstants::twoPi * normalisedTransitionWidth; + const double ds = Decibels::decibelsToGain (stopbandAmplitudedB, static_cast (-300.0)); auto k = std::pow (std::tan ((MathConstants::pi - wt) / 4), 2.0); auto kp = std::sqrt (1.0 - k * k); diff --git a/modules/juce_dsp/filter_design/juce_FilterDesign.h b/modules/juce_dsp/filter_design/juce_FilterDesign.h index e94c5b549d..28f8610b9d 100644 --- a/modules/juce_dsp/filter_design/juce_FilterDesign.h +++ b/modules/juce_dsp/filter_design/juce_FilterDesign.h @@ -56,7 +56,7 @@ struct FilterDesign It generates linear phase filters coefficients. Note: The flatTop WindowingMethod generates an impulse response with a - maximum amplitude higher than one, and might be normalized if necessary + maximum amplitude higher than one, and might be normalised if necessary depending on the applications. @param frequency the cutoff frequency of the low-pass filter @@ -71,7 +71,7 @@ struct FilterDesign FloatType beta = static_cast (2)); /** This a variant of the function designFIRLowpassWindowMethod, which allows the - user to specify a transition width and an attenuation in dB, + user to specify a transition width and a negative gain in dB, to get a low-pass filter using the Kaiser windowing function, with calculated values of the filter order and of the beta parameter, to satisfy the constraints. @@ -79,14 +79,14 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param attenuationdB the attenuation in dB expected in the stop band + @param amplitudedB the maximum amplitude in dB expected in the stop band (must be negative) */ static FIRCoefficientsPtr designFIRLowpassKaiserMethod (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType attenuationdB); + FloatType normalisedTransitionWidth, + FloatType amplitudedB); /** This method is also a variant of the function designFIRLowpassWindowMethod, using @@ -98,14 +98,14 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design @param order the order of the filter - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band @param spline between 1.0 and 4.0, indicates how much the transition is curved, with 1.0 meaning a straight line */ static FIRCoefficientsPtr designFIRLowpassTransitionMethod (FloatType frequency, double sampleRate, size_t order, - FloatType normalizedTransitionWidth, + FloatType normalisedTransitionWidth, FloatType spline); /** This method generates a FIR::Coefficients for a low-pass filter, by @@ -117,14 +117,14 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design @param order the order of the filter - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band @param stopBandWeight between 1.0 and 100.0, indicates how much we want attenuation in the stop band, against some oscillation in the pass band */ static FIRCoefficientsPtr designFIRLowpassLeastSquaresMethod (FloatType frequency, double sampleRate, size_t order, - FloatType normalizedTransitionWidth, + FloatType normalisedTransitionWidth, FloatType stopBandWeight); /** This method generates a FIR::Coefficients for a low-pass filter, with @@ -135,12 +135,12 @@ struct FilterDesign It generates linear phase filters coefficients. - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param attenuationdB the attenuation in dB expected in the stop band + @param amplitudedB the maximum amplitude in dB expected in the stop band (must be negative) */ - static FIRCoefficientsPtr designFIRLowpassHalfBandEquirippleMethod (FloatType normalizedTransitionWidth, - FloatType attenuationdB); + static FIRCoefficientsPtr designFIRLowpassHalfBandEquirippleMethod (FloatType normalisedTransitionWidth, + FloatType amplitudedB); //============================================================================== /** This method returns an array of IIR::Coefficients, made to be used in @@ -152,16 +152,16 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param passbandAttenuationdB the lowest attenuation in dB expected in the pass band - @param stopbandAttenuationdB the attenuation in dB expected in the stop band + @param passbandAmplitudedB the highest gain in dB expected in the pass band (must be negative) + @param stopbandAmplitudedB the gain in dB expected in the stop band (must be negative) */ static ReferenceCountedArray designIIRLowpassHighOrderButterworthMethod (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB); + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB); //============================================================================== /** This method returns an array of IIR::Coefficients, made to be used in @@ -199,15 +199,15 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param passbandAttenuationdB the lowest attenuation in dB expected in the pass band - @param stopbandAttenuationdB the attenuation in dB expected in the stop band + @param passbandAmplitudedB the highest amplitude in dB expected in the pass band (must be negative) + @param stopbandAmplitudedB the lowest amplitude in dB expected in the stop band (must be negative) */ static ReferenceCountedArray designIIRLowpassHighOrderChebyshev1Method (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB); + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB); /** This method returns an array of IIR::Coefficients, made to be used in cascaded IIRFilters, providing a minimum phase low-pass filter without any @@ -218,15 +218,15 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param passbandAttenuationdB the lowest attenuation in dB expected in the pass band - @param stopbandAttenuationdB the attenuation in dB expected in the stop band + @param passbandAmplitudedB the highest amplitude in dB expected in the pass band (must be negative) + @param stopbandAmplitudedB the lowest amplitude in dB expected in the stop band (must be negative) */ static ReferenceCountedArray designIIRLowpassHighOrderChebyshev2Method (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB); + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB); /** This method returns an array of IIR::Coefficients, made to be used in cascaded IIR::Filters, providing a minimum phase low-pass filter with ripples @@ -237,15 +237,15 @@ struct FilterDesign @param frequency the cutoff frequency of the low-pass filter @param sampleRate the sample rate being used in the filter design - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param passbandAttenuationdB the lowest attenuation in dB expected in the pass band - @param stopbandAttenuationdB the attenuation in dB expected in the stop band + @param passbandAmplitudedB the highest amplitude in dB expected in the pass band (must be negative) + @param stopbandAmplitudedB the lowest amplitude in dB expected in the stop band (must be negative) */ static ReferenceCountedArray designIIRLowpassHighOrderEllipticMethod (FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB); + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB); /** The structure returned by the function designIIRLowpassHalfBandPolyphaseAllpassMethod. @@ -278,21 +278,21 @@ struct FilterDesign The gain of the resulting pass-band is 6 dB, so don't forget to compensate it if you want to use that method for something else than two times oversampling. - @param normalizedTransitionWidth the normalized size between 0 and 0.5 of the transition + @param normalisedTransitionWidth the normalised size between 0 and 0.5 of the transition between the pass band and the stop band - @param stopbandAttenuationdB the attenuation in dB expected in the stop band + @param stopbandAmplitudedB the maximum amplitude in dB expected in the stop band (must be negative) */ - static IIRPolyphaseAllpassStructure designIIRLowpassHalfBandPolyphaseAllpassMethod (FloatType normalizedTransitionWidth, - FloatType stopbandAttenuationdB); + static IIRPolyphaseAllpassStructure designIIRLowpassHalfBandPolyphaseAllpassMethod (FloatType normalisedTransitionWidth, + FloatType stopbandAmplitudedB); private: //============================================================================== static Array getPartialImpulseResponseHn (int n, double kp); static ReferenceCountedArray designIIRLowpassHighOrderGeneralMethod (int type, FloatType frequency, double sampleRate, - FloatType normalizedTransitionWidth, - FloatType passbandAttenuationdB, - FloatType stopbandAttenuationdB); + FloatType normalisedTransitionWidth, + FloatType passbandAmplitudedB, + FloatType stopbandAmplitudedB); FilterDesign() = delete; }; diff --git a/modules/juce_dsp/frequency/juce_Convolution.cpp b/modules/juce_dsp/frequency/juce_Convolution.cpp index bdbce85bde..6fa4fdc899 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.cpp +++ b/modules/juce_dsp/frequency/juce_Convolution.cpp @@ -61,7 +61,7 @@ struct ConvolutionEngine bool wantsStereo = true; bool wantsTrimming = true; - bool wantsNormalization = true; + bool wantsNormalisation = true; int64 wantedSize = 0; int finalSize = 0; @@ -345,7 +345,7 @@ struct Convolution::Pimpl : private Thread changeImpulseResponseSize, changeStereo, changeTrimming, - changeNormalization, + changeNormalisation, changeIgnore, numChangeRequestTypes }; @@ -437,7 +437,7 @@ struct Convolution::Pimpl : private Thread abstractFifo.finishedWrite (size1 + size2); } - /** Reads requests from the fifo */ + /** Reads requests from the fifo. */ void readFromFifo (ChangeRequest& type, juce::var& parameter) { int start1, size1, start2, size2; @@ -458,7 +458,7 @@ struct Convolution::Pimpl : private Thread abstractFifo.finishedRead (size1 + size2); } - /** Returns the number of requests that still need to be processed */ + /** Returns the number of requests that still need to be processed. */ int getNumRemainingEntries() const noexcept { return abstractFifo.getNumReady(); @@ -624,14 +624,14 @@ struct Convolution::Pimpl : private Thread } break; - case ChangeRequest::changeNormalization: + case ChangeRequest::changeNormalisation: { - bool newWantsNormalization = requestsParameter[n]; + bool newWantsNormalisation = requestsParameter[n]; - if (currentInfo.wantsNormalization != newWantsNormalization) + if (currentInfo.wantsNormalisation != newWantsNormalisation) changeLevel = jmax (1, changeLevel); - currentInfo.wantsNormalization = newWantsNormalization; + currentInfo.wantsNormalisation = newWantsNormalisation; } break; @@ -814,16 +814,16 @@ private: if (isThreadRunning() && threadShouldExit()) return; - if (currentInfo.wantsNormalization) + if (currentInfo.wantsNormalisation) { if (currentInfo.originalNumChannels > 1) { - normalizeImpulseResponse (currentInfo.buffer->getWritePointer (0), (int) currentInfo.finalSize, 1.0); - normalizeImpulseResponse (currentInfo.buffer->getWritePointer (1), (int) currentInfo.finalSize, 1.0); + normaliseImpulseResponse (currentInfo.buffer->getWritePointer (0), (int) currentInfo.finalSize, 1.0); + normaliseImpulseResponse (currentInfo.buffer->getWritePointer (1), (int) currentInfo.finalSize, 1.0); } else { - normalizeImpulseResponse (currentInfo.buffer->getWritePointer (0), (int) currentInfo.finalSize, 1.0); + normaliseImpulseResponse (currentInfo.buffer->getWritePointer (0), (int) currentInfo.finalSize, 1.0); } } @@ -951,8 +951,8 @@ private: impulseResponse.copyFrom (1, 0, impulseResponse, 0, 0, (int) currentInfo.finalSize); } - /** Normalization of the impulse response based on its energy. */ - void normalizeImpulseResponse (float* samples, int numSamples, double factorResampling) const + /** Normalisation of the impulse response based on its energy. */ + void normaliseImpulseResponse (float* samples, int numSamples, double factorResampling) const { auto magnitude = 0.0f; @@ -1028,7 +1028,7 @@ private: SpinLock processLock; // a necessary lock to use with this temporary buffer AudioBuffer impulseResponseOriginal; // a buffer with the original impulse response - AudioBuffer impulseResponse; // a buffer with the impulse response trimmed, resampled, resized and normalized + AudioBuffer impulseResponse; // a buffer with the impulse response trimmed, resampled, resized and normalised //============================================================================== OwnedArray engines; // the 4 convolution engines being used @@ -1056,7 +1056,7 @@ Convolution::~Convolution() void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceDataSize, bool wantsStereo, bool wantsTrimming, size_t size, - bool wantsNormalization) + bool wantsNormalisation) { if (sourceData == nullptr) return; @@ -1068,7 +1068,7 @@ void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceData Pimpl::ChangeRequest::changeImpulseResponseSize, Pimpl::ChangeRequest::changeStereo, Pimpl::ChangeRequest::changeTrimming, - Pimpl::ChangeRequest::changeNormalization }; + Pimpl::ChangeRequest::changeNormalisation }; Array sourceParameter; @@ -1079,13 +1079,13 @@ void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceData juce::var (static_cast (wantedSize)), juce::var (wantsStereo), juce::var (wantsTrimming), - juce::var (wantsNormalization) }; + juce::var (wantsNormalisation) }; pimpl->addToFifo (types, parameters, 5); } void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wantsStereo, - bool wantsTrimming, size_t size, bool wantsNormalization) + bool wantsTrimming, size_t size, bool wantsNormalisation) { if (! fileImpulseResponse.existsAsFile()) return; @@ -1097,7 +1097,7 @@ void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wan Pimpl::ChangeRequest::changeImpulseResponseSize, Pimpl::ChangeRequest::changeStereo, Pimpl::ChangeRequest::changeTrimming, - Pimpl::ChangeRequest::changeNormalization }; + Pimpl::ChangeRequest::changeNormalisation }; Array sourceParameter; @@ -1108,20 +1108,20 @@ void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wan juce::var (static_cast (wantedSize)), juce::var (wantsStereo), juce::var (wantsTrimming), - juce::var (wantsNormalization) }; + juce::var (wantsNormalisation) }; pimpl->addToFifo (types, parameters, 5); } void Convolution::copyAndLoadImpulseResponseFromBuffer (AudioBuffer& buffer, - double bufferSampleRate, bool wantsStereo, bool wantsTrimming, bool wantsNormalization, size_t size) + double bufferSampleRate, bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, size_t size) { copyAndLoadImpulseResponseFromBlock (AudioBlock (buffer), bufferSampleRate, - wantsStereo, wantsTrimming, wantsNormalization, size); + wantsStereo, wantsTrimming, wantsNormalisation, size); } void Convolution::copyAndLoadImpulseResponseFromBlock (AudioBlock block, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, bool wantsNormalization, size_t size) + bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, size_t size) { jassert (bufferSampleRate > 0); @@ -1137,7 +1137,7 @@ void Convolution::copyAndLoadImpulseResponseFromBlock (AudioBlock block, Pimpl::ChangeRequest::changeImpulseResponseSize, Pimpl::ChangeRequest::changeStereo, Pimpl::ChangeRequest::changeTrimming, - Pimpl::ChangeRequest::changeNormalization }; + Pimpl::ChangeRequest::changeNormalisation }; Array sourceParameter; sourceParameter.add (juce::var ((int) ConvolutionEngine::ProcessingInformation::SourceType::sourceAudioBuffer)); @@ -1147,7 +1147,7 @@ void Convolution::copyAndLoadImpulseResponseFromBlock (AudioBlock block, juce::var (static_cast (wantedSize)), juce::var (wantsStereo), juce::var (wantsTrimming), - juce::var (wantsNormalization) }; + juce::var (wantsNormalisation) }; pimpl->addToFifo (types, parameters, 5); } diff --git a/modules/juce_dsp/frequency/juce_Convolution.h b/modules/juce_dsp/frequency/juce_Convolution.h index 45b805f02a..d8c242fb71 100644 --- a/modules/juce_dsp/frequency/juce_Convolution.h +++ b/modules/juce_dsp/frequency/juce_Convolution.h @@ -96,11 +96,11 @@ public: @param wantsTrimming requests to trim the start and the end of the impulse response @param size the expected size for the impulse response after loading, can be set to 0 for requesting maximum original impulse response size - @param wantsNormalization requests to normalize the impulse response amplitude + @param wantsNormalisation requests to normalise the impulse response amplitude */ void loadImpulseResponse (const void* sourceData, size_t sourceDataSize, bool wantsStereo, bool wantsTrimming, size_t size, - bool wantsNormalization = true); + bool wantsNormalisation = true); /** This function loads an impulse response from an audio file on any drive. It can load any of the audio formats registered in JUCE, and performs some @@ -111,11 +111,11 @@ public: @param wantsTrimming requests to trim the start and the end of the impulse response @param size the expected size for the impulse response after loading, can be set to 0 for requesting maximum original impulse response size - @param wantsNormalization requests to normalize the impulse response amplitude + @param wantsNormalisation requests to normalise the impulse response amplitude */ void loadImpulseResponse (const File& fileImpulseResponse, bool wantsStereo, bool wantsTrimming, size_t size, - bool wantsNormalization = true); + bool wantsNormalisation = true); /** This function loads an impulse response from an audio buffer, which is copied before doing anything else. Performs some resampling and @@ -125,12 +125,12 @@ public: @param bufferSampleRate the sampleRate of the data in the AudioBuffer @param wantsStereo requests to process both stereo channels or only one mono channel @param wantsTrimming requests to trim the start and the end of the impulse response - @param wantsNormalization requests to normalize the impulse response amplitude + @param wantsNormalisation requests to normalise the impulse response amplitude @param size the expected size for the impulse response after loading, can be set to 0 for requesting maximum original impulse response size */ void copyAndLoadImpulseResponseFromBuffer (AudioBuffer& buffer, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, bool wantsNormalization, + bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, size_t size); /** This function loads an impulse response from an audio block, which is @@ -141,12 +141,12 @@ public: @param bufferSampleRate the sampleRate of the data in the AudioBuffer @param wantsStereo requests to process both stereo channels or only one channel @param wantsTrimming requests to trim the start and the end of the impulse response - @param wantsNormalization requests to normalize the impulse response amplitude + @param wantsNormalisation requests to normalise the impulse response amplitude @param size the expected size for the impulse response after loading, -1 for maximum length */ void copyAndLoadImpulseResponseFromBlock (AudioBlock block, double bufferSampleRate, - bool wantsStereo, bool wantsTrimming, bool wantsNormalization, + bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, size_t size); diff --git a/modules/juce_dsp/frequency/juce_Windowing.cpp b/modules/juce_dsp/frequency/juce_Windowing.cpp index 79fbc7cd07..6a2c62e375 100644 --- a/modules/juce_dsp/frequency/juce_Windowing.cpp +++ b/modules/juce_dsp/frequency/juce_Windowing.cpp @@ -37,22 +37,22 @@ static inline FloatType ncos (size_t order, size_t i, size_t size) noexcept } template -WindowingFunction::WindowingFunction (size_t size, WindowingMethod type, bool normalize, FloatType beta) +WindowingFunction::WindowingFunction (size_t size, WindowingMethod type, bool normalise, FloatType beta) { - fillWindowingTables (size, type, normalize, beta); + fillWindowingTables (size, type, normalise, beta); } template void WindowingFunction::fillWindowingTables (size_t size, WindowingMethod type, - bool normalize, FloatType beta) noexcept + bool normalise, FloatType beta) noexcept { windowTable.resize (static_cast (size)); - fillWindowingTables (windowTable.getRawDataPointer(), size, type, normalize, beta); + fillWindowingTables (windowTable.getRawDataPointer(), size, type, normalise, beta); } template void WindowingFunction::fillWindowingTables (FloatType* samples, size_t size, - WindowingMethod type, bool normalize, + WindowingMethod type, bool normalise, FloatType beta) noexcept { switch (type) @@ -151,7 +151,7 @@ void WindowingFunction::fillWindowingTables (FloatType* samples, size } // DC frequency amplitude must be one - if (normalize) + if (normalise) { FloatType sum (0); @@ -181,14 +181,14 @@ const char* WindowingFunction::getWindowingMethodName (WindowingMetho case hamming: return "Hamming"; case blackman: return "Blackman"; case blackmanHarris: return "Blackman-Harris"; - case flatTop: return "FlatTop"; + case flatTop: return "Flat Top"; case kaiser: return "Kaiser"; default: jassertfalse; return ""; } } -template struct WindowingFunction; -template struct WindowingFunction; +template class WindowingFunction; +template class WindowingFunction; } // namespace dsp } // namespace juce diff --git a/modules/juce_dsp/frequency/juce_Windowing.h b/modules/juce_dsp/frequency/juce_Windowing.h index 018748eab2..907e65a334 100644 --- a/modules/juce_dsp/frequency/juce_Windowing.h +++ b/modules/juce_dsp/frequency/juce_Windowing.h @@ -31,13 +31,20 @@ namespace dsp /** A class which provides multiple windowing functions useful for filter design - and spectrum analyzers + and spectrum analyzers. + + The different functions provided here can be used by creating either a + WindowingFunction object, or a static function to fill an array with the + windowing method samples. @tags{DSP} */ template -struct WindowingFunction +class JUCE_API WindowingFunction { +public: + //============================================================================== + /** The windowing methods available. */ enum WindowingMethod { rectangular = 0, @@ -52,22 +59,46 @@ struct WindowingFunction }; //============================================================================== + /** This constructor automatically fills a buffer of the specified size using + the fillWindowingTables function and the specified arguments. + + @see fillWindowingTables + */ WindowingFunction (size_t size, WindowingMethod, - bool normalize = true, FloatType beta = 0); + bool normalise = true, FloatType beta = 0); //============================================================================== - /** Fills the content of an array with a given windowing method table */ + /** Fills the content of the object array with a given windowing method table. + + @param size the size of the destination buffer allocated in the object + @param type the type of windowing method being used + @param normalise if the result must be normalised, creating a DC amplitude + response of one + @param beta an optional argument useful only for Kaiser's method + which must be positive and sets the properties of the + method (bandwidth and attenuation increases with beta) + */ void fillWindowingTables (size_t size, WindowingMethod type, - bool normalize = true, FloatType beta = 0) noexcept; + bool normalise = true, FloatType beta = 0) noexcept; - /** Fills the content of an array with a given windowing method table */ + /** Fills the content of an array with a given windowing method table. + + @param samples the destination buffer pointer + @param size the size of the destination buffer allocated in the object + @param type the type of windowing method being used + @param normalise if the result must be normalised, creating a DC amplitude + response of one + @param beta an optional argument useful only for Kaiser's method, + which must be positive and sets the properties of the + method (bandwidth and attenuation increases with beta) + */ static void fillWindowingTables (FloatType* samples, size_t size, WindowingMethod, - bool normalize = true, FloatType beta = 0) noexcept; + bool normalise = true, FloatType beta = 0) noexcept; - /** Multiply the content of a buffer with the given window */ + /** Multiplies the content of a buffer with the given window. */ void multiplyWithWindowingTable (FloatType* samples, size_t size) noexcept; - /** Returns the name of a given windowing method */ + /** Returns the name of a given windowing method. */ static const char* getWindowingMethodName (WindowingMethod) noexcept; diff --git a/modules/juce_dsp/processors/juce_Oversampling.cpp b/modules/juce_dsp/processors/juce_Oversampling.cpp index 4a97ef8863..109047b55c 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.cpp +++ b/modules/juce_dsp/processors/juce_Oversampling.cpp @@ -116,14 +116,14 @@ struct Oversampling2TimesEquirippleFIR : public Oversampling::Overs using ParentType = typename Oversampling::OversamplingStage; Oversampling2TimesEquirippleFIR (size_t numChans, - SampleType normalizedTransitionWidthUp, - SampleType stopbandAttenuationdBUp, - SampleType normalizedTransitionWidthDown, - SampleType stopbandAttenuationdBDown) + SampleType normalisedTransitionWidthUp, + SampleType stopbandAmplitudedBUp, + SampleType normalisedTransitionWidthDown, + SampleType stopbandAmplitudedBDown) : ParentType (numChans, 2) { - coefficientsUp = *dsp::FilterDesign::designFIRLowpassHalfBandEquirippleMethod (normalizedTransitionWidthUp, stopbandAttenuationdBUp); - coefficientsDown = *dsp::FilterDesign::designFIRLowpassHalfBandEquirippleMethod (normalizedTransitionWidthDown, stopbandAttenuationdBDown); + coefficientsUp = *dsp::FilterDesign::designFIRLowpassHalfBandEquirippleMethod (normalisedTransitionWidthUp, stopbandAmplitudedBUp); + coefficientsDown = *dsp::FilterDesign::designFIRLowpassHalfBandEquirippleMethod (normalisedTransitionWidthDown, stopbandAmplitudedBDown); auto N = coefficientsUp.getFilterOrder() + 1; stateUp.setSize (static_cast (this->numChannels), static_cast (N)); @@ -268,17 +268,17 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling::Oversa using ParentType = typename Oversampling::OversamplingStage; Oversampling2TimesPolyphaseIIR (size_t numChans, - SampleType normalizedTransitionWidthUp, - SampleType stopbandAttenuationdBUp, - SampleType normalizedTransitionWidthDown, - SampleType stopbandAttenuationdBDown) + SampleType normalisedTransitionWidthUp, + SampleType stopbandAmplitudedBUp, + SampleType normalisedTransitionWidthDown, + SampleType stopbandAmplitudedBDown) : ParentType (numChans, 2) { - auto structureUp = dsp::FilterDesign::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalizedTransitionWidthUp, stopbandAttenuationdBUp); + auto structureUp = dsp::FilterDesign::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalisedTransitionWidthUp, stopbandAmplitudedBUp); auto coeffsUp = getCoefficients (structureUp); latency = static_cast (-(coeffsUp.getPhaseForFrequency (0.0001, 1.0)) / (0.0001 * MathConstants::twoPi)); - auto structureDown = dsp::FilterDesign::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalizedTransitionWidthDown, stopbandAttenuationdBDown); + auto structureDown = dsp::FilterDesign::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalisedTransitionWidthDown, stopbandAmplitudedBDown); auto coeffsDown = getCoefficients (structureDown); latency += static_cast (-(coeffsDown.getPhaseForFrequency (0.0001, 1.0)) / (0.0001 * MathConstants::twoPi)); @@ -599,22 +599,22 @@ void Oversampling::addDummyOversamplingStage() template void Oversampling::addOversamplingStage (FilterType type, - float normalizedTransitionWidthUp, - float stopbandAttenuationdBUp, - float normalizedTransitionWidthDown, - float stopbandAttenuationdBDown) + float normalisedTransitionWidthUp, + float stopbandAmplitudedBUp, + float normalisedTransitionWidthDown, + float stopbandAmplitudedBDown) { if (type == FilterType::filterHalfBandPolyphaseIIR) { stages.add (new Oversampling2TimesPolyphaseIIR (numChannels, - normalizedTransitionWidthUp, stopbandAttenuationdBUp, - normalizedTransitionWidthDown, stopbandAttenuationdBDown)); + normalisedTransitionWidthUp, stopbandAmplitudedBUp, + normalisedTransitionWidthDown, stopbandAmplitudedBDown)); } else { stages.add (new Oversampling2TimesEquirippleFIR (numChannels, - normalizedTransitionWidthUp, stopbandAttenuationdBUp, - normalizedTransitionWidthDown, stopbandAttenuationdBDown)); + normalisedTransitionWidthUp, stopbandAmplitudedBUp, + normalisedTransitionWidthDown, stopbandAmplitudedBDown)); } factorOversampling *= 2; diff --git a/modules/juce_dsp/processors/juce_Oversampling.h b/modules/juce_dsp/processors/juce_Oversampling.h index d8befe0235..8dedeac47f 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.h +++ b/modules/juce_dsp/processors/juce_Oversampling.h @@ -40,14 +40,14 @@ namespace dsp The principle of oversampling is to increase the sample rate of a given non-linear process, to prevent it from creating aliasing. Oversampling works - by upsampling N times the input signal, processing the upsampling signal - with the increased internal sample rate, and downsample the result to get + by upsampling N times the input signal, processing the upsampled signal + with the increased internal sample rate, and downsampling the result to get back the original processing sample rate. Choose between FIR or IIR filtering depending on your needs in term of latency and phase distortion. With FIR filters, the phase is linear but the - latency is maximum. With IIR filtering, the phase is compromised around the - Nyquist frequency but the latency is minimum. + latency is maximised. With IIR filtering, the phase is compromised around the + Nyquist frequency but the latency is minimised. @see FilterDesign. @@ -70,9 +70,6 @@ public: Constructor of the oversampling class. All the processing parameters must be provided at the creation of the oversampling object. - Note: You might want to create a class inheriting from Oversampling with a - different constructor if you need more control on what happens in the process. - @param numChannels the number of channels to process with this object @param factor the processing will perform 2 ^ factor times oversampling @param type the type of filter design employed for filtering during @@ -86,8 +83,13 @@ public: FilterType type, bool isMaxQuality = true); - /** Default constructor of the oversampling class, which can be used to create an + /** The default constructor of the oversampling class, which can be used to create an empty object and then add the appropriate stages. + + Note: This creates a "dummy" oversampling stage, which needs to be removed first + before adding proper oversampling stages. + + @see clearOversamplingStages, addOversamplingStage */ explicit Oversampling (size_t numChannels = 1); @@ -134,12 +136,49 @@ public: void processSamplesDown (dsp::AudioBlock& outputBlock) noexcept; //=============================================================================== - void addOversamplingStage (FilterType, - float normalizedTransitionWidthUp, float stopbandAttenuationdBUp, - float normalizedTransitionWidthDown, float stopbandAttenuationdBDown); + /** Adds a new oversampling stage to the Oversampling class, multiplying the + current oversampling factor by two. This is used with the default constructor + to create custom oversampling chains, requiring a call to the + clearOversamplingStages before any addition. + Note: Upsampling and downsampling filtering have different purposes, the + former removes upsampling artefacts while the latter removes useless frequency + content created by the oversampled process, so usually the attenuation is + increased when upsampling compared to downsampling. + + @param type the type of filter design employed for filtering + during oversampling + @param normalisedTransitionWidthUp a value between 0 and 0.5 which specifies how much + the transition between passband and stopband is + steep, for upsampling filtering (the lower the better) + @param stopbandAmplitudedBUp the amplitude in dB in the stopband for upsampling + filtering, must be negative + @param normalisedTransitionWidthDown a value between 0 and 0.5 which specifies how much + the transition between passband and stopband is + steep, for downsampling filtering (the lower the better) + @param stopbandAmplitudedBDown the amplitude in dB in the stopband for downsampling + filtering, must be negative + + @see clearOversamplingStages + */ + void addOversamplingStage (FilterType, + float normalisedTransitionWidthUp, float stopbandAmplitudedBUp, + float normalisedTransitionWidthDown, float stopbandAmplitudedBDown); + + /** Adds a new "dummy" oversampling stage, which does nothing to the signal. Using + one can be useful if your application features a customisable oversampling factor + and if you want to select the current one from an OwnedArray without changing + anything in the processing code. + + @see OwnedArray, clearOversamplingStages, addOversamplingStage + */ void addDummyOversamplingStage(); + /** Removes all the previously registered oversampling stages, so you can add + your own from scratch. + + @see addOversamplingStage, addDummyOversamplingStage + */ void clearOversamplingStages(); //===============================================================================