Improved: Shelving filters (LS(C), HS(C)) can now also use Q instead of slope.

This commit is contained in:
jthedering committed 2019-06-09 18:26:52 +00:00
1 parent 916eab4528
commit a7fc5de925
7 files changed
+91 -53

No files matched your search

+8 -10
View File
@@ -22,7 +22,7 @@
using namespace std;
BiQuad::BiQuad(Type type, double dbGain, double freq, double srate, double bandwidthOrQOrS, bool isBandwidth)
BiQuad::BiQuad(Type type, double dbGain, double freq, double srate, double bandwidthOrQOrS, bool isBandwidthOrS)
{
double A;
if (type == PEAKING || type == LOW_SHELF || type == HIGH_SHELF)
@@ -33,17 +33,15 @@ BiQuad::BiQuad(Type type, double dbGain, double freq, double srate, double bandw
double sn = sin(omega);
double cs = cos(omega);
double alpha;
double beta = -1;
if (type == LOW_SHELF || type == HIGH_SHELF) // S
{
alpha = sn / 2 * sqrt((A + 1 / A) * (1 / bandwidthOrQOrS - 1) + 2);
beta = 2 * sqrt(A) * alpha;
}
else if (isBandwidth) // BW
alpha = sn * sinh(M_LN2 / 2 * bandwidthOrQOrS * omega / sn);
else // Q
if (!isBandwidthOrS) // Q
alpha = sn / (2 * bandwidthOrQOrS);
else if (type == LOW_SHELF || type == HIGH_SHELF) // S
alpha = sn / 2 * sqrt((A + 1 / A) * (1 / bandwidthOrQOrS - 1) + 2);
else // BW
alpha = sn * sinh(M_LN2 / 2 * bandwidthOrQOrS * omega / sn);
double beta = 2 * sqrt(A) * alpha;
double b0, b1, b2, a0, a1, a2;
+1 -1
View File
@@ -35,7 +35,7 @@ public:
};
BiQuad() {}
BiQuad(Type type, double dbGain, double freq, double srate, double bandwidthOrQOrS, bool isBandwidth);
BiQuad(Type type, double dbGain, double freq, double srate, double bandwidthOrQOrS, bool isBandwidthOrS);
__forceinline
void removeDenormals()
+14 -6
View File
@@ -23,8 +23,8 @@
using namespace std;
BiQuadFilter::BiQuadFilter(BiQuad::Type type, double dbGain, double freq, double bandwidthOrQOrS, bool isBandwidth, bool isCornerFreq)
: type(type), dbGain(dbGain), freq(freq), bandwidthOrQOrS(bandwidthOrQOrS), isBandwidth(isBandwidth), isCornerFreq(isCornerFreq)
BiQuadFilter::BiQuadFilter(BiQuad::Type type, double dbGain, double freq, double bandwidthOrQOrS, bool isBandwidthOrS, bool isCornerFreq)
: type(type), dbGain(dbGain), freq(freq), bandwidthOrQOrS(bandwidthOrQOrS), isBandwidthOrS(isBandwidthOrS), isCornerFreq(isCornerFreq)
{
channelCount = 0;
biquads = NULL;
@@ -46,8 +46,16 @@ vector<wstring> BiQuadFilter::initialize(float sampleRate, unsigned maxFrameCoun
double biquadFreq = freq;
if (isCornerFreq && (type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF))
{
double s = bandwidthOrQOrS;
if (!isBandwidthOrS) // Q
{
double q = bandwidthOrQOrS;
double a = pow(10, dbGain / 40);
s = 1.0 / ((1.0 / (q * q) - 2.0) / (a + 1.0 / a) + 1.0);
}
// frequency adjustment for DCX2496
double centerFreqFactor = pow(10.0, abs(dbGain) / 80.0 / bandwidthOrQOrS);
double centerFreqFactor = pow(10.0, abs(dbGain) / 80.0 / s);
if (type == BiQuad::LOW_SHELF)
biquadFreq *= centerFreqFactor;
else
@@ -56,7 +64,7 @@ vector<wstring> BiQuadFilter::initialize(float sampleRate, unsigned maxFrameCoun
for (unsigned i = 0; i < channelCount; i++)
{
new(biquads + i)BiQuad(type, dbGain, biquadFreq, sampleRate, bandwidthOrQOrS, isBandwidth);
new(biquads + i)BiQuad(type, dbGain, biquadFreq, sampleRate, bandwidthOrQOrS, isBandwidthOrS);
}
return channelNames;
@@ -100,9 +108,9 @@ double BiQuadFilter::getBandwidthOrQOrS() const
return bandwidthOrQOrS;
}
bool BiQuadFilter::getIsBandwidth() const
bool BiQuadFilter::getIsBandwidthOrS() const
{
return isBandwidth;
return isBandwidthOrS;
}
bool BiQuadFilter::getIsCornerFreq() const
+5 -5
View File
@@ -26,9 +26,9 @@
class BiQuadFilter : public IFilter
{
public:
BiQuadFilter(BiQuad::Type type, double dbGain, double freq, double bandwidthOrQOrS, bool isBandwidth, bool isCornerFreq);
virtual ~BiQuadFilter();
bool getInPlace() override {return true;}
BiQuadFilter(BiQuad::Type type, double dbGain, double freq, double bandwidthOrQOrS, bool isBandwidthOrS, bool isCornerFreq);
virtual~BiQuadFilter();
bool getInPlace() override{return true;}
std::vector<std::wstring> initialize(float sampleRate, unsigned maxFrameCount, std::vector<std::wstring> channelNames) override;
void process(float** output, float** input, unsigned frameCount) override;
@@ -36,7 +36,7 @@ public:
double getDbGain() const;
double getFreq() const;
double getBandwidthOrQOrS() const;
bool getIsBandwidth() const;
bool getIsBandwidthOrS() const;
bool getIsCornerFreq() const;
private:
@@ -44,7 +44,7 @@ private:
double dbGain;
double freq;
double bandwidthOrQOrS;
bool isBandwidth;
bool isBandwidthOrS;
bool isCornerFreq;
size_t channelCount;
+11 -13
View File
@@ -93,7 +93,7 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
double freq = 0;
double gain = 0;
double bandwidthOrQOrS = 0;
bool isBandwidth = false;
bool isBandwidthOrS = false;
bool isCornerFreq = false;
bool error = false;
@@ -134,14 +134,9 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
found = regex_search(parameters, match, regexQ);
if (found)
{
if (type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
TraceF(L"Ignoring Q for filter of type %s", typeDescription.c_str());
else
{
wstring qString = match.str(1);
bandwidthOrQOrS = wcstod(qString.c_str(), NULL);
stream << " and Q " << bandwidthOrQOrS;
}
wstring qString = match.str(1);
bandwidthOrQOrS = wcstod(qString.c_str(), NULL);
stream << " and Q " << bandwidthOrQOrS;
}
found = regex_search(parameters, match, regexBW);
@@ -153,7 +148,7 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
{
wstring bwString = match.str(1);
bandwidthOrQOrS = wcstod(bwString.c_str(), NULL);
isBandwidth = true;
isBandwidthOrS = true;
stream << " and bandwidth " << bandwidthOrQOrS << " octaves";
}
}
@@ -167,6 +162,7 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
{
wstring slopeString = match.str(1);
bandwidthOrQOrS = wcstod(slopeString.c_str(), NULL);
isBandwidthOrS = true;
stream << " and slope " << bandwidthOrQOrS << " dB";
}
}
@@ -185,6 +181,7 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
else if (type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
{
bandwidthOrQOrS = 0.9; // found out by experimentation with RoomEQWizard
isBandwidthOrS = true;
}
else if (type == BiQuad::NOTCH)
{
@@ -193,8 +190,9 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
}
else if (type == BiQuad::LOW_SHELF || type == BiQuad::HIGH_SHELF)
{
// Maximum S is 1 for 12 dB
bandwidthOrQOrS /= 12.0;
if (isBandwidthOrS)
// Maximum S is 1 for 12 dB
bandwidthOrQOrS /= 12.0;
if (typeString[typeString.length() - 1] != L'C')
isCornerFreq = true;
}
@@ -204,7 +202,7 @@ vector<IFilter*> BiQuadFilterFactory::createFilter(const wstring& configPath, ws
TraceF(L"%s", stream.str().c_str());
void* mem = MemoryHelper::alloc(sizeof(BiQuadFilter));
filter = new(mem) BiQuadFilter(type, gain, freq, bandwidthOrQOrS, isBandwidth, isCornerFreq);
filter = new(mem) BiQuadFilter(type, gain, freq, bandwidthOrQOrS, isBandwidthOrS, isCornerFreq);
}
}
else if (typeString != L"None")