| @@ -42,18 +42,18 @@ typename FIR::Coefficients<FloatType>::Ptr | |||
| auto* result = new typename FIR::Coefficients<FloatType> (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<FloatType> (normalizedFrequency * 2); | |||
| c[i] = static_cast<FloatType> (normalisedFrequency * 2); | |||
| } | |||
| else | |||
| { | |||
| auto indice = MathConstants<double>::pi * (static_cast<double> (i) - 0.5 * static_cast<double> (order)); | |||
| c[i] = static_cast<FloatType> (std::sin (2.0 * indice * normalizedFrequency) / indice); | |||
| c[i] = static_cast<FloatType> (std::sin (2.0 * indice * normalisedFrequency) / indice); | |||
| } | |||
| } | |||
| @@ -66,23 +66,23 @@ typename FIR::Coefficients<FloatType>::Ptr | |||
| template <typename FloatType> | |||
| typename FIR::Coefficients<FloatType>::Ptr | |||
| FilterDesign<FloatType>::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<FloatType> (0.1102 * (-attenuationdB - 8.7)); | |||
| else if (attenuationdB <= 21) | |||
| beta = static_cast<FloatType> (0.5842 * std::pow (-attenuationdB - 21, 0.4) + 0.07886 * (-attenuationdB - 21)); | |||
| if (amplitudedB < -50) | |||
| beta = static_cast<FloatType> (0.1102 * (-amplitudedB - 8.7)); | |||
| else if (amplitudedB <= 21) | |||
| beta = static_cast<FloatType> (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<double>::twoPi))) | |||
| : roundToInt (std::ceil (5.79 / (normalizedTransitionWidth * MathConstants<double>::twoPi))); | |||
| int order = amplitudedB < -21 ? roundToInt (std::ceil ((-amplitudedB - 7.95) / (2.285 * normalisedTransitionWidth * MathConstants<double>::twoPi))) | |||
| : roundToInt (std::ceil (5.79 / (normalisedTransitionWidth * MathConstants<double>::twoPi))); | |||
| jassert (order >= 0); | |||
| @@ -94,14 +94,14 @@ typename FIR::Coefficients<FloatType>::Ptr | |||
| template <typename FloatType> | |||
| typename FIR::Coefficients<FloatType>::Ptr | |||
| FilterDesign<FloatType>::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<FloatType> (sampleRate); | |||
| auto normalisedFrequency = frequency / static_cast<FloatType> (sampleRate); | |||
| auto* result = new typename FIR::Coefficients<FloatType> (order + 1u); | |||
| auto* c = result->getRawCoefficients(); | |||
| @@ -110,13 +110,13 @@ typename FIR::Coefficients<FloatType>::Ptr | |||
| { | |||
| if (i == order / 2 && order % 2 == 0) | |||
| { | |||
| c[i] = static_cast<FloatType> (2 * normalizedFrequency); | |||
| c[i] = static_cast<FloatType> (2 * normalisedFrequency); | |||
| } | |||
| else | |||
| { | |||
| auto indice = MathConstants<double>::pi * (i - 0.5 * order); | |||
| auto indice2 = MathConstants<double>::pi * normalizedTransitionWidth * (i - 0.5 * order) / spline; | |||
| c[i] = static_cast<FloatType> (std::sin (2 * indice * normalizedFrequency) | |||
| auto indice2 = MathConstants<double>::pi * normalisedTransitionWidth * (i - 0.5 * order) / spline; | |||
| c[i] = static_cast<FloatType> (std::sin (2 * indice * normalisedFrequency) | |||
| / indice * std::pow (std::sin (indice2) / indice2, spline)); | |||
| } | |||
| } | |||
| @@ -128,18 +128,18 @@ template <typename FloatType> | |||
| typename FIR::Coefficients<FloatType>::Ptr | |||
| FilterDesign<FloatType>::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<double> (frequency) / sampleRate; | |||
| auto normalisedFrequency = static_cast<double> (frequency) / sampleRate; | |||
| auto wp = MathConstants<double>::twoPi * (static_cast<double> (normalizedFrequency - normalizedTransitionWidth / 2.0)); | |||
| auto ws = MathConstants<double>::twoPi * (static_cast<double> (normalizedFrequency + normalizedTransitionWidth / 2.0)); | |||
| auto wp = MathConstants<double>::twoPi * (static_cast<double> (normalisedFrequency - normalisedTransitionWidth / 2.0)); | |||
| auto ws = MathConstants<double>::twoPi * (static_cast<double> (normalisedFrequency + normalisedTransitionWidth / 2.0)); | |||
| auto N = order + 1; | |||
| @@ -236,15 +236,15 @@ typename FIR::Coefficients<FloatType>::Ptr | |||
| template <typename FloatType> | |||
| typename FIR::Coefficients<FloatType>::Ptr | |||
| FilterDesign<FloatType>::designFIRLowpassHalfBandEquirippleMethod (FloatType normalizedTransitionWidth, | |||
| FloatType attenuationdB) | |||
| FilterDesign<FloatType>::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<double>::pi; | |||
| auto wpT = (0.5 - normalisedTransitionWidth) * MathConstants<double>::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<double> FilterDesign<FloatType>::getPartialImpulseResponseHn (int n, doubl | |||
| template <typename FloatType> | |||
| ReferenceCountedArray<IIR::Coefficients<FloatType>> | |||
| FilterDesign<FloatType>::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 <typename FloatType> | |||
| ReferenceCountedArray<IIR::Coefficients<FloatType>> | |||
| FilterDesign<FloatType>::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 <typename FloatType> | |||
| ReferenceCountedArray<IIR::Coefficients<FloatType>> | |||
| FilterDesign<FloatType>::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 <typename FloatType> | |||
| ReferenceCountedArray<IIR::Coefficients<FloatType>> | |||
| FilterDesign<FloatType>::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 <typename FloatType> | |||
| ReferenceCountedArray<IIR::Coefficients<FloatType>> | |||
| FilterDesign<FloatType>::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<IIR::Coefficients<FloatType>> | |||
| template <typename FloatType> | |||
| typename FilterDesign<FloatType>::IIRPolyphaseAllpassStructure | |||
| FilterDesign<FloatType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (FloatType normalizedTransitionWidth, | |||
| FloatType stopbandAttenuationdB) | |||
| FilterDesign<FloatType>::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<double>::twoPi * normalizedTransitionWidth; | |||
| const double ds = Decibels::decibelsToGain (stopbandAttenuationdB, static_cast<FloatType> (-300.0)); | |||
| const double wt = MathConstants<double>::twoPi * normalisedTransitionWidth; | |||
| const double ds = Decibels::decibelsToGain (stopbandAmplitudedB, static_cast<FloatType> (-300.0)); | |||
| auto k = std::pow (std::tan ((MathConstants<double>::pi - wt) / 4), 2.0); | |||
| auto kp = std::sqrt (1.0 - k * k); | |||
| @@ -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<FloatType> (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<IIRCoefficients> 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<IIRCoefficients> 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<IIRCoefficients> 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<IIRCoefficients> 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<double> getPartialImpulseResponseHn (int n, double kp); | |||
| static ReferenceCountedArray<IIRCoefficients> designIIRLowpassHighOrderGeneralMethod (int type, FloatType frequency, double sampleRate, | |||
| FloatType normalizedTransitionWidth, | |||
| FloatType passbandAttenuationdB, | |||
| FloatType stopbandAttenuationdB); | |||
| FloatType normalisedTransitionWidth, | |||
| FloatType passbandAmplitudedB, | |||
| FloatType stopbandAmplitudedB); | |||
| FilterDesign() = delete; | |||
| }; | |||
| @@ -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<float> impulseResponseOriginal; // a buffer with the original impulse response | |||
| AudioBuffer<float> impulseResponse; // a buffer with the impulse response trimmed, resampled, resized and normalized | |||
| AudioBuffer<float> impulseResponse; // a buffer with the impulse response trimmed, resampled, resized and normalised | |||
| //============================================================================== | |||
| OwnedArray<ConvolutionEngine> 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<juce::var> sourceParameter; | |||
| @@ -1079,13 +1079,13 @@ void Convolution::loadImpulseResponse (const void* sourceData, size_t sourceData | |||
| juce::var (static_cast<int64> (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<juce::var> sourceParameter; | |||
| @@ -1108,20 +1108,20 @@ void Convolution::loadImpulseResponse (const File& fileImpulseResponse, bool wan | |||
| juce::var (static_cast<int64> (wantedSize)), | |||
| juce::var (wantsStereo), | |||
| juce::var (wantsTrimming), | |||
| juce::var (wantsNormalization) }; | |||
| juce::var (wantsNormalisation) }; | |||
| pimpl->addToFifo (types, parameters, 5); | |||
| } | |||
| void Convolution::copyAndLoadImpulseResponseFromBuffer (AudioBuffer<float>& 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<float> (buffer), bufferSampleRate, | |||
| wantsStereo, wantsTrimming, wantsNormalization, size); | |||
| wantsStereo, wantsTrimming, wantsNormalisation, size); | |||
| } | |||
| void Convolution::copyAndLoadImpulseResponseFromBlock (AudioBlock<float> 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<float> block, | |||
| Pimpl::ChangeRequest::changeImpulseResponseSize, | |||
| Pimpl::ChangeRequest::changeStereo, | |||
| Pimpl::ChangeRequest::changeTrimming, | |||
| Pimpl::ChangeRequest::changeNormalization }; | |||
| Pimpl::ChangeRequest::changeNormalisation }; | |||
| Array<juce::var> sourceParameter; | |||
| sourceParameter.add (juce::var ((int) ConvolutionEngine::ProcessingInformation::SourceType::sourceAudioBuffer)); | |||
| @@ -1147,7 +1147,7 @@ void Convolution::copyAndLoadImpulseResponseFromBlock (AudioBlock<float> block, | |||
| juce::var (static_cast<int64> (wantedSize)), | |||
| juce::var (wantsStereo), | |||
| juce::var (wantsTrimming), | |||
| juce::var (wantsNormalization) }; | |||
| juce::var (wantsNormalisation) }; | |||
| pimpl->addToFifo (types, parameters, 5); | |||
| } | |||
| @@ -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<float>& 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<float> block, double bufferSampleRate, | |||
| bool wantsStereo, bool wantsTrimming, bool wantsNormalization, | |||
| bool wantsStereo, bool wantsTrimming, bool wantsNormalisation, | |||
| size_t size); | |||
| @@ -37,22 +37,22 @@ static inline FloatType ncos (size_t order, size_t i, size_t size) noexcept | |||
| } | |||
| template <typename FloatType> | |||
| WindowingFunction<FloatType>::WindowingFunction (size_t size, WindowingMethod type, bool normalize, FloatType beta) | |||
| WindowingFunction<FloatType>::WindowingFunction (size_t size, WindowingMethod type, bool normalise, FloatType beta) | |||
| { | |||
| fillWindowingTables (size, type, normalize, beta); | |||
| fillWindowingTables (size, type, normalise, beta); | |||
| } | |||
| template <typename FloatType> | |||
| void WindowingFunction<FloatType>::fillWindowingTables (size_t size, WindowingMethod type, | |||
| bool normalize, FloatType beta) noexcept | |||
| bool normalise, FloatType beta) noexcept | |||
| { | |||
| windowTable.resize (static_cast<int> (size)); | |||
| fillWindowingTables (windowTable.getRawDataPointer(), size, type, normalize, beta); | |||
| fillWindowingTables (windowTable.getRawDataPointer(), size, type, normalise, beta); | |||
| } | |||
| template <typename FloatType> | |||
| void WindowingFunction<FloatType>::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<FloatType>::fillWindowingTables (FloatType* samples, size | |||
| } | |||
| // DC frequency amplitude must be one | |||
| if (normalize) | |||
| if (normalise) | |||
| { | |||
| FloatType sum (0); | |||
| @@ -181,14 +181,14 @@ const char* WindowingFunction<FloatType>::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<float>; | |||
| template struct WindowingFunction<double>; | |||
| template class WindowingFunction<float>; | |||
| template class WindowingFunction<double>; | |||
| } // namespace dsp | |||
| } // namespace juce | |||
| @@ -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 <typename FloatType> | |||
| 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; | |||
| /** Fills the content of an array with a given windowing method table */ | |||
| bool normalise = true, FloatType beta = 0) noexcept; | |||
| /** 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; | |||
| @@ -116,14 +116,14 @@ struct Oversampling2TimesEquirippleFIR : public Oversampling<SampleType>::Overs | |||
| using ParentType = typename Oversampling<SampleType>::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<SampleType>::designFIRLowpassHalfBandEquirippleMethod (normalizedTransitionWidthUp, stopbandAttenuationdBUp); | |||
| coefficientsDown = *dsp::FilterDesign<SampleType>::designFIRLowpassHalfBandEquirippleMethod (normalizedTransitionWidthDown, stopbandAttenuationdBDown); | |||
| coefficientsUp = *dsp::FilterDesign<SampleType>::designFIRLowpassHalfBandEquirippleMethod (normalisedTransitionWidthUp, stopbandAmplitudedBUp); | |||
| coefficientsDown = *dsp::FilterDesign<SampleType>::designFIRLowpassHalfBandEquirippleMethod (normalisedTransitionWidthDown, stopbandAmplitudedBDown); | |||
| auto N = coefficientsUp.getFilterOrder() + 1; | |||
| stateUp.setSize (static_cast<int> (this->numChannels), static_cast<int> (N)); | |||
| @@ -268,17 +268,17 @@ struct Oversampling2TimesPolyphaseIIR : public Oversampling<SampleType>::Oversa | |||
| using ParentType = typename Oversampling<SampleType>::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<SampleType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalizedTransitionWidthUp, stopbandAttenuationdBUp); | |||
| auto structureUp = dsp::FilterDesign<SampleType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalisedTransitionWidthUp, stopbandAmplitudedBUp); | |||
| auto coeffsUp = getCoefficients (structureUp); | |||
| latency = static_cast<SampleType> (-(coeffsUp.getPhaseForFrequency (0.0001, 1.0)) / (0.0001 * MathConstants<double>::twoPi)); | |||
| auto structureDown = dsp::FilterDesign<SampleType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalizedTransitionWidthDown, stopbandAttenuationdBDown); | |||
| auto structureDown = dsp::FilterDesign<SampleType>::designIIRLowpassHalfBandPolyphaseAllpassMethod (normalisedTransitionWidthDown, stopbandAmplitudedBDown); | |||
| auto coeffsDown = getCoefficients (structureDown); | |||
| latency += static_cast<SampleType> (-(coeffsDown.getPhaseForFrequency (0.0001, 1.0)) / (0.0001 * MathConstants<double>::twoPi)); | |||
| @@ -599,22 +599,22 @@ void Oversampling<SampleType>::addDummyOversamplingStage() | |||
| template <typename SampleType> | |||
| void Oversampling<SampleType>::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<SampleType> (numChannels, | |||
| normalizedTransitionWidthUp, stopbandAttenuationdBUp, | |||
| normalizedTransitionWidthDown, stopbandAttenuationdBDown)); | |||
| normalisedTransitionWidthUp, stopbandAmplitudedBUp, | |||
| normalisedTransitionWidthDown, stopbandAmplitudedBDown)); | |||
| } | |||
| else | |||
| { | |||
| stages.add (new Oversampling2TimesEquirippleFIR<SampleType> (numChannels, | |||
| normalizedTransitionWidthUp, stopbandAttenuationdBUp, | |||
| normalizedTransitionWidthDown, stopbandAttenuationdBDown)); | |||
| normalisedTransitionWidthUp, stopbandAmplitudedBUp, | |||
| normalisedTransitionWidthDown, stopbandAmplitudedBDown)); | |||
| } | |||
| factorOversampling *= 2; | |||
| @@ -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<SampleType>& outputBlock) noexcept; | |||
| //=============================================================================== | |||
| /** 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 normalizedTransitionWidthUp, float stopbandAttenuationdBUp, | |||
| float normalizedTransitionWidthDown, float stopbandAttenuationdBDown); | |||
| 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(); | |||
| //=============================================================================== | |||