how to get the biquad filter as eq?

farbstoff-fabrik

how to get the biquad filter as eq?

Post 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
User avatar
utdgrant
Posts: 679
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: how to get the biquad filter as eq?

Post 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.
______________________
Dome Music Technologies
farbstoff-fabrik

Re: how to get the biquad filter as eq?

Post 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
User avatar
utdgrant
Posts: 679
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: how to get the biquad filter as eq?

Post 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
______________________
Dome Music Technologies
farbstoff-fabrik

Re: how to get the biquad filter as eq?

Post by farbstoff-fabrik »

If I do - i'll post it :)
farbstoff-fabrik

Re: how to get the biquad filter as eq?

Post 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 :D thanks in advance!
User avatar
utdgrant
Posts: 679
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: how to get the biquad filter as eq?

Post 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 :D 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
BiQuadTestbedFrontPanel.jpg (27.12 KiB) Viewed 43597 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.
______________________
Dome Music Technologies
User avatar
utdgrant
Posts: 679
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: how to get the biquad filter as eq?

Post 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.
______________________
Dome Music Technologies
User avatar
Waverley Instruments
Posts: 154
Joined: Thu May 05, 2022 2:10 pm

Re: how to get the biquad filter as eq?

Post 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
User avatar
utdgrant
Posts: 679
Joined: Wed Apr 07, 2021 8:58 am
Location: Scotland
Contact:

Re: how to get the biquad filter as eq?

Post 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.
______________________
Dome Music Technologies
Post Reply

Return to “Module Designer”