mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-26 02:35:38 +08:00
Ref T730, namespace BiQuadFilter
This commit is contained in:
committed by
Mat Sutcliffe
parent
1c0dc8b34c
commit
4dbe1c49c8
@@ -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 <QtMath>
|
||||
#include <algorithm>
|
||||
|
||||
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<float>(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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "blacksound/audioutilities.h"
|
||||
#include <QDebug>
|
||||
|
||||
using namespace BlackSound::Dsp;
|
||||
|
||||
namespace BlackSound
|
||||
{
|
||||
namespace SampleProvider
|
||||
@@ -52,5 +54,5 @@ namespace BlackSound
|
||||
{
|
||||
m_outputGain = outputGain;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
@@ -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<BiQuadFilter> m_filters;
|
||||
QVector<Dsp::BiQuadFilter> m_filters;
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
Reference in New Issue
Block a user