diff --git a/src/blacksound/dsp/biquadfilter.cpp b/src/blacksound/dsp/biquadfilter.cpp index 35459e788..e19a2e74a 100644 --- a/src/blacksound/dsp/biquadfilter.cpp +++ b/src/blacksound/dsp/biquadfilter.cpp @@ -1,101 +1,116 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + #include "biquadfilter.h" #include #include -float BiQuadFilter::transform(float inSample) + +namespace BlackSound { - // compute result - double result = a0 * inSample + a1 * x1 + a2 * x2 - a3 * y1 - a4 * y2; + namespace Dsp + { + float BiQuadFilter::transform(float inSample) + { + // compute result + double result = a0 * inSample + a1 * x1 + a2 * x2 - a3 * y1 - a4 * y2; - // shift x1 to x2, sample to x1 - x2 = x1; - x1 = inSample; + // shift x1 to x2, sample to x1 + x2 = x1; + x1 = inSample; - // shift y1 to y2, result to y1 - y2 = y1; - y1 = (float)result; + // shift y1 to y2, result to y1 + y2 = y1; + y1 = static_cast(result); - return y1; -} + return y1; + } -void BiQuadFilter::setCoefficients(double aa0, double aa1, double aa2, double b0, double b1, double b2) -{ - // precompute the coefficients - a0 = b0 / aa0; - a1 = b1 / aa0; - a2 = b2 / aa0; - a3 = aa1 / aa0; - a4 = aa2 / aa0; -} + void BiQuadFilter::setCoefficients(double aa0, double aa1, double aa2, double b0, double b1, double b2) + { + // precompute the coefficients + a0 = b0 / aa0; + a1 = b1 / aa0; + a2 = b2 / aa0; + a3 = aa1 / aa0; + a4 = aa2 / aa0; + } -void BiQuadFilter::setLowPassFilter(float sampleRate, float cutoffFrequency, float q) -{ - // H(s) = 1 / (s^2 + s/Q + 1) - auto w0 = 2 * M_PI * cutoffFrequency / sampleRate; - auto cosw0 = qCos(w0); - auto alpha = qSin(w0) / (2 * q); + void BiQuadFilter::setLowPassFilter(float sampleRate, float cutoffFrequency, float q) + { + // H(s) = 1 / (s^2 + s/Q + 1) + auto w0 = 2 * M_PI * cutoffFrequency / sampleRate; + auto cosw0 = qCos(w0); + auto alpha = qSin(w0) / (2 * q); - auto b0 = (1 - cosw0) / 2; - auto b1 = 1 - cosw0; - auto b2 = (1 - cosw0) / 2; - auto aa0 = 1 + alpha; - auto aa1 = -2 * cosw0; - auto aa2 = 1 - alpha; - setCoefficients(aa0, aa1, aa2, b0, b1, b2); -} + auto b0 = (1 - cosw0) / 2; + auto b1 = 1 - cosw0; + auto b2 = (1 - cosw0) / 2; + auto aa0 = 1 + alpha; + auto aa1 = -2 * cosw0; + auto aa2 = 1 - alpha; + setCoefficients(aa0, aa1, aa2, b0, b1, b2); + } -void BiQuadFilter::setPeakingEq(float sampleRate, float centreFrequency, float q, float dbGain) -{ - // H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) - auto w0 = 2 * M_PI * centreFrequency / sampleRate; - auto cosw0 = qCos(w0); - auto sinw0 = qSin(w0); - auto alpha = sinw0 / (2 * q); - auto a = qPow(10, dbGain / 40); // TODO: should we square root this value? + void BiQuadFilter::setPeakingEq(float sampleRate, float centreFrequency, float q, float dbGain) + { + // H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) + auto w0 = 2 * M_PI * centreFrequency / sampleRate; + auto cosw0 = qCos(w0); + auto sinw0 = qSin(w0); + auto alpha = sinw0 / (2 * q); + auto a = qPow(10, dbGain / 40); // TODO: should we square root this value? - auto b0 = 1 + alpha * a; - auto b1 = -2 * cosw0; - auto b2 = 1 - alpha * a; - auto aa0 = 1 + alpha / a; - auto aa1 = -2 * cosw0; - auto aa2 = 1 - alpha / a; - setCoefficients(aa0, aa1, aa2, b0, b1, b2); -} + auto b0 = 1 + alpha * a; + auto b1 = -2 * cosw0; + auto b2 = 1 - alpha * a; + auto aa0 = 1 + alpha / a; + auto aa1 = -2 * cosw0; + auto aa2 = 1 - alpha / a; + setCoefficients(aa0, aa1, aa2, b0, b1, b2); + } -void BiQuadFilter::setHighPassFilter(float sampleRate, float cutoffFrequency, float q) -{ - // H(s) = s^2 / (s^2 + s/Q + 1) - auto w0 = 2 * M_PI * cutoffFrequency / sampleRate; - auto cosw0 = qCos(w0); - auto alpha = qSin(w0) / (2 * q); + void BiQuadFilter::setHighPassFilter(float sampleRate, float cutoffFrequency, float q) + { + // H(s) = s^2 / (s^2 + s/Q + 1) + auto w0 = 2 * M_PI * cutoffFrequency / sampleRate; + auto cosw0 = qCos(w0); + auto alpha = qSin(w0) / (2 * q); - auto b0 = (1 + cosw0) / 2; - auto b1 = -(1 + cosw0); - auto b2 = (1 + cosw0) / 2; - auto aa0 = 1 + alpha; - auto aa1 = -2 * cosw0; - auto aa2 = 1 - alpha; - setCoefficients(aa0, aa1, aa2, b0, b1, b2); -} + auto b0 = (1 + cosw0) / 2; + auto b1 = -(1 + cosw0); + auto b2 = (1 + cosw0) / 2; + auto aa0 = 1 + alpha; + auto aa1 = -2 * cosw0; + auto aa2 = 1 - alpha; + setCoefficients(aa0, aa1, aa2, b0, b1, b2); + } -BiQuadFilter BiQuadFilter::lowPassFilter(float sampleRate, float cutoffFrequency, float q) -{ - BiQuadFilter filter; - filter.setLowPassFilter(sampleRate, cutoffFrequency, q); - return filter; -} + BiQuadFilter BiQuadFilter::lowPassFilter(float sampleRate, float cutoffFrequency, float q) + { + BiQuadFilter filter; + filter.setLowPassFilter(sampleRate, cutoffFrequency, q); + return filter; + } -BiQuadFilter BiQuadFilter::highPassFilter(float sampleRate, float cutoffFrequency, float q) -{ - BiQuadFilter filter; - filter.setHighPassFilter(sampleRate, cutoffFrequency, q); - return filter; -} + BiQuadFilter BiQuadFilter::highPassFilter(float sampleRate, float cutoffFrequency, float q) + { + BiQuadFilter filter; + filter.setHighPassFilter(sampleRate, cutoffFrequency, q); + return filter; + } -BiQuadFilter BiQuadFilter::peakingEQ(float sampleRate, float centreFrequency, float q, float dbGain) -{ - BiQuadFilter filter; - filter.setPeakingEq(sampleRate, centreFrequency, q, dbGain); - return filter; -} + BiQuadFilter BiQuadFilter::peakingEQ(float sampleRate, float centreFrequency, float q, float dbGain) + { + BiQuadFilter filter; + filter.setPeakingEq(sampleRate, centreFrequency, q, dbGain); + return filter; + } + } // ns +} // ns diff --git a/src/blacksound/dsp/biquadfilter.h b/src/blacksound/dsp/biquadfilter.h index 0bf430804..33fcb7dcd 100644 --- a/src/blacksound/dsp/biquadfilter.h +++ b/src/blacksound/dsp/biquadfilter.h @@ -1,35 +1,54 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + #ifndef BIQUADFILTER_H #define BIQUADFILTER_H #include "blacksound/blacksoundexport.h" -class BiQuadFilter +namespace BlackSound { -public: - BiQuadFilter() = default; + namespace Dsp + { + //! Digital biquad filter + class BiQuadFilter + { + public: + //! Ctor + BiQuadFilter() = default; - float transform(float inSample); - void setCoefficients(double aa0, double aa1, double aa2, double b0, double b1, double b2); - void setLowPassFilter(float sampleRate, float cutoffFrequency, float q); - void setPeakingEq(float sampleRate, float centreFrequency, float q, float dbGain); - void setHighPassFilter(float sampleRate, float cutoffFrequency, float q); + float transform(float inSample); + void setCoefficients(double aa0, double aa1, double aa2, double b0, double b1, double b2); + void setLowPassFilter(float sampleRate, float cutoffFrequency, float q); + void setPeakingEq(float sampleRate, float centreFrequency, float q, float dbGain); + void setHighPassFilter(float sampleRate, float cutoffFrequency, float q); - static BiQuadFilter lowPassFilter(float sampleRate, float cutoffFrequency, float q); - static BiQuadFilter highPassFilter(float sampleRate, float cutoffFrequency, float q); - static BiQuadFilter peakingEQ(float sampleRate, float centreFrequency, float q, float dbGain); -private: - double a0; - double a1; - double a2; - double a3; - double a4; + static BiQuadFilter lowPassFilter(float sampleRate, float cutoffFrequency, float q); + static BiQuadFilter highPassFilter(float sampleRate, float cutoffFrequency, float q); + static BiQuadFilter peakingEQ(float sampleRate, float centreFrequency, float q, float dbGain); - // state - float x1 = 0.0; - float x2 = 0.0; - float y1 = 0.0; - float y2 = 0.0; -}; + private: + double a0; + double a1; + double a2; + double a3; + double a4; -#endif // BIQUADFILTER_H + // state + float x1 = 0.0; + float x2 = 0.0; + float y1 = 0.0; + float y2 = 0.0; + }; + } // ns +} // ns + +#endif // guard diff --git a/src/blacksound/sampleprovider/equalizersampleprovider.cpp b/src/blacksound/sampleprovider/equalizersampleprovider.cpp index cecc53d9e..2a37e8cb4 100644 --- a/src/blacksound/sampleprovider/equalizersampleprovider.cpp +++ b/src/blacksound/sampleprovider/equalizersampleprovider.cpp @@ -2,6 +2,8 @@ #include "blacksound/audioutilities.h" #include +using namespace BlackSound::Dsp; + namespace BlackSound { namespace SampleProvider @@ -52,5 +54,5 @@ namespace BlackSound { m_outputGain = outputGain; } - } -} + } // ns +} // ns diff --git a/src/blacksound/sampleprovider/equalizersampleprovider.h b/src/blacksound/sampleprovider/equalizersampleprovider.h index e58870f25..64cfe6d2b 100644 --- a/src/blacksound/sampleprovider/equalizersampleprovider.h +++ b/src/blacksound/sampleprovider/equalizersampleprovider.h @@ -52,11 +52,10 @@ namespace BlackSound void setupPreset(EqualizerPresets preset); ISampleProvider *m_sourceProvider = nullptr; - - int m_channels = 1; - bool m_bypass = false; + int m_channels = 1; + bool m_bypass = false; double m_outputGain = 1.0; - QVector m_filters; + QVector m_filters; }; } // ns } // ns