Page 1 of 2
how to get the biquad filter as eq?
Posted: Thu May 12, 2022 6:35 am
by farbstoff-fabrik
Hi there,
I am working on a module and bascially i would like to add a eq that bootst the frequency at 300 (similar to the stock CA 3 band equaliser). I have spend 2 evenings on this but for some reason my approach doesn't work.
I am using a biquadfilter with a peakingeq as filtertype. freq set to 300,0 and gain is set by a knob with a value of 1 to 12. I presume 12 is the dB gain you are adding?
(from memory...
--
BiQuadFilter = eq new BiQuadFilter(filtertype.peakingeq, 300.0, 0, 0);
--
eq.SetFrequency(300.0);
eq.SetdbGain(boostKnob.GetValue());
signalOut = eq.ProssesSample(signalIN);
--
When I start turning the knob, it doesn't boost anything. The input signal seems unprocessed.
Any help is very very much appreciated!
Thanks in advance!
-Matt
Re: how to get the biquad filter as eq?
Posted: Thu May 12, 2022 8:25 am
by utdgrant
In the constructor, the parameters are:
BiQuadFilter(
FilterType type,
double frequency,
double gain,
double bandwidth)
The bandwidth parameter is defined as the number of octaves, and you've set it to 0.0.
This seems like asking for trouble!
Try it at 1.0 instead, and see if that makes any difference.
Re: how to get the biquad filter as eq?
Posted: Thu May 12, 2022 9:47 am
by farbstoff-fabrik
Ah, it might be the decimal and number
have you had experience with the biquad? I'll try later today to get it to work.
btw: also on this topic:
viewtopic.php?p=1606&hilit=biquad#p1606
Re: how to get the biquad filter as eq?
Posted: Thu May 12, 2022 9:58 am
by utdgrant
farbstoff-fabrik wrote: ↑Thu May 12, 2022 9:47 am
have you had experience with the biquad? I'll try later today to get it to work.
No, no experience at all.
I've seen Bi-Quad coefficient calculators online, and most of them don't let you
set 'Q' to be lower than 0.1. I suspect it will lead to divide-by-zero errors
somewhere down the line.
Your problem might have nothing to do with this. It's just a suggestion.
Hope you find your answer,
Grant
Re: how to get the biquad filter as eq?
Posted: Thu May 12, 2022 12:56 pm
by farbstoff-fabrik
If I do - i'll post it

Re: how to get the biquad filter as eq?
Posted: Thu May 12, 2022 6:01 pm
by farbstoff-fabrik
In the meantime I have spoken to a few other developers and it seems I am not the only one experiencing issues setting this biquad up. After another afternoon and half a evening i gave up. Could someone from cherryaudio clarify, please

thanks in advance!
Re: how to get the biquad filter as eq?
Posted: Sat Feb 01, 2025 9:49 am
by utdgrant
farbstoff-fabrik wrote: ↑Thu May 12, 2022 6:01 pm
In the meantime I have spoken to a few other developers and it seems I am not the only one experiencing issues setting this biquad up. After another afternoon and half a evening i gave up. Could someone from cherryaudio clarify, please

thanks in advance!
I was experimenting with the BiQuadFilter class in Voltage Module Developer. I wasn't too sure about the subtleties of the API, so I built a testbed module which allowed me to tweak the parameters of each filter type in real time. The parameters are Frequency (in Hz), Gain (in dB) and Bandwidth (in octaves).

- BiQuadTestbedFrontPanel.jpg (27.12 KiB) Viewed 45028 times
The filter types available are: Low-Pass, High-Pass, Band-Pass, Notch, Low Shelf, High Shelf, and Peaking EQ.
I discovered that the Gain setting had no effect on the Low-Pass, High-Pass, Band-Pass and Notch filter types. Similarly, the Bandwidth setting had no effect on the Low Shelf and High Shelf filter types. Only the Peaking EQ filter type responded to changes in both Gain and Bandwidth.
I've made a
short YouTube Video to demonstrate the responses of the different filter types.
Re: how to get the biquad filter as eq?
Posted: Sat Feb 01, 2025 10:29 am
by utdgrant
I've added the source code for the BiQuad Testbed Module to the Dome Tech Open-Source Archive. You can download it from the bottom of the
Documentation Page).
Here is the User Variables & Functions section:
Code: Select all
private BiQuadFilter bqbpFilter = new BiQuadFilter(BiQuadFilter.FilterType.BANDPASS, 1000.0, 1.0, 1.0);
private BiQuadFilter bqhpFilter = new BiQuadFilter(BiQuadFilter.FilterType.HIGHPASS, 1000.0, 1.0, 1.0);
private BiQuadFilter bqhsFilter = new BiQuadFilter(BiQuadFilter.FilterType.HIGHSHELF, 1000.0, 1.0, 1.0);
private BiQuadFilter bqlpFilter = new BiQuadFilter(BiQuadFilter.FilterType.LOWPASS, 1000.0, 1.0, 1.0);
private BiQuadFilter bqlsFilter = new BiQuadFilter(BiQuadFilter.FilterType.LOWSHELF, 1000.0, 1.0, 1.0);
private BiQuadFilter bqntFilter = new BiQuadFilter(BiQuadFilter.FilterType.NOTCH, 1000.0, 1.0, 1.0);
private BiQuadFilter bqpkFilter = new BiQuadFilter(BiQuadFilter.FilterType.PEAKINGEQ, 1000.0, 1.0, 1.0);
private SmoothValue smoothFreq = new SmoothValue();
private float previousFreqCVin = 0.0f;
private double previousFreqCVmult = 1.0;
Notify:
Code: Select all
switch( notification )
{
case Knob_Changed: // doubleValue is the new VoltageKnob value
{
if (component == knobBandwidth)
{
bqbpFilter.SetBandwidth(doubleValue);
bqhpFilter.SetBandwidth(doubleValue);
bqhsFilter.SetBandwidth(doubleValue);
bqlpFilter.SetBandwidth(doubleValue);
bqlsFilter.SetBandwidth(doubleValue);
bqntFilter.SetBandwidth(doubleValue);
bqpkFilter.SetBandwidth(doubleValue);
}
else if (component == knobGain)
{
bqbpFilter.SetdBGain(doubleValue);
bqhpFilter.SetdBGain(doubleValue);
bqhsFilter.SetdBGain(doubleValue);
bqlpFilter.SetdBGain(doubleValue);
bqlsFilter.SetdBGain(doubleValue);
bqntFilter.SetdBGain(doubleValue);
bqpkFilter.SetdBGain(doubleValue);
}
}
break;
case Slider_Changed: // doubleValue is the new slider value
{
if (component == sliderFreq)
{
smoothFreq.SetValue(doubleValue);
}
}
break;
And ProcessSample():
Code: Select all
double tmpDouble;
int filterMode;
double audioDouble;
float tempFloat;
audioDouble = inputJack1.GetValue();
tmpDouble = smoothFreq.GetSmoothValue();
tempFloat = (float)(inputFreq.GetValue());
if (tempFloat != previousFreqCVin)
{
previousFreqCVin = tempFloat;
previousFreqCVmult = Values.FastTwoToTheX(previousFreqCVin);
}
tmpDouble *= previousFreqCVmult;
tmpDouble = Math.min(tmpDouble, 20000.0);
tmpDouble = Math.max(tmpDouble, 20.0);
filterMode = (int)(knobMode.GetValue());
switch (filterMode)
{
case 1: // Bandpass
{
bqbpFilter.SetFrequency(tmpDouble);
audioDouble = bqbpFilter.ProcessSample(audioDouble);
}
break;
case 2: // Highpass
{
bqhpFilter.SetFrequency(tmpDouble);
audioDouble = bqhpFilter.ProcessSample(audioDouble);
}
break;
case 3: // High Shelf
{
bqhsFilter.SetFrequency(tmpDouble);
audioDouble = bqhsFilter.ProcessSample(audioDouble);
}
break;
case 4: // Lowpass
{
bqlpFilter.SetFrequency(tmpDouble);
audioDouble = bqlpFilter.ProcessSample(audioDouble);
}
break;
case 5: // Low Shelf
{
bqlsFilter.SetFrequency(tmpDouble);
audioDouble = bqlsFilter.ProcessSample(audioDouble);
}
break;
case 6: // Notch
{
bqntFilter.SetFrequency(tmpDouble);
audioDouble = bqntFilter.ProcessSample(audioDouble);
}
break;
case 7: // Peaking EQ
{
bqpkFilter.SetFrequency(tmpDouble);
audioDouble = bqpkFilter.ProcessSample(audioDouble);
}
break;
default: // Bypass
{
// Leave audioDouble unaffected;
}
break;
}
outputJack1.SetValue(audioDouble);
I discovered that I had to limit the requested frequency of the filter, as it could cause a mathematical overflow and lock the object up. This was especially evident when driving the PEAKINGEQ filter type.
Re: how to get the biquad filter as eq?
Posted: Sat Feb 01, 2025 12:52 pm
by Waverley Instruments
Just to chip-in here...
Biquad filters have known side-effects - if you modulate the cutoff frequency they can "blow-up" (edit: basically a divide by zero).
For set frequencies, they work fine but tweaking the cutoff in realtime with a knob on the UI is asking for trouble
Cheers, -Rob @ WI
Re: how to get the biquad filter as eq?
Posted: Sun Feb 02, 2025 12:07 am
by utdgrant
Waverley Instruments wrote: ↑Sat Feb 01, 2025 12:52 pm
Just to chip-in here...
Biquad filters have known side-effects - if you modulate the cutoff frequency they can "blow-up" (edit: basically a divide by zero).
Hmmmm, interesting. Thanks, Rob. Definitely something to watch out for. I wonder if Request For Music ever encountered weird behaviour with the
RFM_VCF module, when operating in BiQuad mode?
I basically built the testbed module so that I could get a handle on how the various parameters interact with the overall response of the filter. Far easier to allow real-time tweaking than an endless cycle of adjust-compile-run.
By doing this exercise, I was able to answer
farbstoff-fabrik's initial query regarding the PEAKINGEQ mode. That's to say - it definitely
does work as described in the documentation.
HOWEVER, to really get your head round it in an intuitive manner, there's no substitute for real-time tweaking via knobs and sliders. Real-time listening/monitoring of the output also lets you fine-tune the required parameter values for your intended application. Once you've figured out the right settings for all the parameters,
then you can fix them as constants in your code.