Do you know guy can find some filters?

I’m looking for filters to use in a a project that could be updated realtime. Im just looking for the basics and some of the crazier ones like ladder butterworth?

You can probably pluck/hack these apart for what you need:

Oh awesome thanks man!

Those should work I’ve seen the Vinnie filters but not the dim’s which seem right up my alley!

Any chance you know where to find a way to display a filter from it’s biquad coefficients?

I don’t recall entirely off-hand, but it’s possible that Daniel’s already covered this in his repo: GitHub - ffAudio/PluginGuiMagic: Examples for foleys_gui_magic - the styleable plugin gui

1 Like

Ive looked at that before when I first started but didn’t understand it too much. I may be confused but I thought it used the Juce class to plot a filter response.

I was looking for something bi-quad → response.
There was one project on git hub a few years back but it wasn’t too accurate.

I’m just curious if I’m going about this in the wrong way.

I found this…

Math :

           a0 + a1 z + a2 z^2 + ... + an z^n
H(z) = -----------------------------------------
           b0 + b1 z + b2 z^2 + ... + bn z^n

H(w) = H(z) where z = e^jw = cos(w) + jsin(w)

       Frequency (Hz)
w = ------------------- x 2pi (Radians)
      Sample Rate (Hz)

Code :

#include <complex>
using cmpx = std::complex<float>;

cmpx calc_freq_response (float frequency,
                         float sample_rate,
                         size_t order,
                         const float* a,
                         const float* b) 
{
    float w = 2.0 * pi * frequency / sample_rate;
    cmpx z (cos(w), sin(w));

    cmpx num (0.0, 0.0);
    cmpx den (0.0, 0.0);
    cmpx zn (1.0, 0.0);

    for (auto n = 0; n < order; n++) 
    {
        num += a[n] * zn;
        den += b[n] * zn;
        zn *= z;
    }

    return num / den;
}

Magnitude is std::abs(H), phase is std::arg(H).

cpp reference on std::complex: std::complex - cppreference.com

The only “gotcha” is the sign of the denominator coefficients. Depending on your source they may need to be flipped.

1 Like

I had a question about how to make the filters more stable while moving the frequency

If I’ve understood the request correctly, you’re looking for ways to play around with filter coefficients safely in real-time?

Direct Form II Transposed is the way to go.

You can create some vectors for storing your audio (Xn, Yn, etc) and variables for your coeffs (a0 through b2):

private:

    //==============================================================================
    std::vector<SampleType> Xn_1, Xn_2, Yn_1, Yn_2;

    //==============================================================================
    SampleType b0_ = 1.0, b1_ = 0.0, b2_ = 0.0, a0_ = 1.0, a1_ = 0.0, a2_ = 0.0;

Prepare and access the variables here:

template <typename SampleType>
void Transformations<SampleType>::coefficients(SampleType b0, SampleType b1, SampleType b2, SampleType a0, SampleType a1, SampleType a2)
{
    a0_ = (static_cast <SampleType>(1.0) / a0);    // best leave this at (1.0)!!!
    a1_ = (static_cast <SampleType>((a1 * a0_) * SampleType (-1.0)));
    a2_ = (static_cast <SampleType>((a2 * a0_) * SampleType (-1.0)));
    b0_ = (static_cast <SampleType>(b0 * a0_));
    b1_ = (static_cast <SampleType>(b1 * a0_));
    b2_ = (static_cast <SampleType>(b2 * a0_));
}

Apply your coefficients to inputSample[channel] via DFII transposed:

template <typename SampleType>
SampleType Transformations<SampleType>::directFormIITransposed(int channel, SampleType inputValue)
{
    SampleType Xn = inputValue;

    SampleType Yn = ((Xn * b0_) + (Xn_2[(size_t)channel]));

    Xn_2[(size_t)channel] = ((Xn * b1_) + (Xn_1[(size_t)channel]) + (Yn * a1_));
    Xn_1[(size_t)channel] = ((Xn * b2_) + (Yn * a2_));

    return Yn;
}

Don’t forget to call “resize” on the vectors using the number of channels to process.

You can use available methods to convert from “freq”, “gain”, and “Q” (or whatever you want to call them) into coeffs b0 through a2. Or, if you’re curious, you can attach params to the coefficients directly. I don’t really recommend doing it though, especially on this 2nd-order design - too complicated. Best leave a0 at (1.0) or else the filter explodes. All the rest should often move together, not independently. The 1st-order variety has less coeffs, so less chance of blowing up (I have working code for this also, if curious).

EDIT: If you want to flip the sign of the coefficients, simply change a0 to negative, as in (-1.0). But otherwise, best leave this one coeff alone :slight_smile:

The “transposed” forms are much more modulation-friendly, mostly thanks to the order of the unit delay and coefficient gain multipliers. This is before even adding a parameter smoother.

I’ve been working on this sort of “workbench filter” class lately, just out of curiosity - still well under construction, but feel free to browse.

Some code and other stuff about Biquad coefficients

I forgot to mention, you can also call the coefficient PTR’s from elsewhere using a “get” method, to display them on a GUI label or something, if you’d just like to view them in real-time without manipulating them directly. I’ll likely do this on my own workbench filter at some point.

I will get back to you once I try to carefully implement this among 40 filters! This looks solid, paired with creating a filter object in prepare to play then performing modulation in the block!

I just saw the git hub link, I will check it out! Good looking out, on the Direct Form II Transposed!

I also thought about implementing a step parameter smoother that creates a new filter along each step, like Big Tick’s comment.

I have tried the lowpass filter parameter smoother in the past, however it peaks at 99% of the value inputed.

I’m currently building a synth and think most filters are fine with cleaning the variables every prepare to play. Unless you are changing the order, that shouldn’t be done in real time! haha.

My filters will be controlled by envelope and lfo. So we’ll have to see. I didn’t realize Transposed 2 was the most stable though!

I’ve started formalizing my general-purpose Biquad filter class, implemented as a simple .cpp/.h with (currently un-smoothed) param float inputs for Freq, Res (0 to 1), and Gain (peak-filter mode only), plus param choice inputs for Filter Type and choice of Direct Transform to use. Vectors are all resized on Prepare, zeroed in Reset, and snapped to zero.

StoneyDSP/Biquads: Multi-mode Biquad filter for audio analysis purposes (github.com)

I’ll be adding many more filter types in the next few days, including hopefully some one-poles. This can be a pretty good set of building blocks for other filter structures. In time, I’ll be looking more at de-cramping techniques (on the other repo I posted).

FWIW, the factory TPT filters (so called “ZDF”) within the DSP module are pretty hard to beat. You can greatly extend the variety of outputs on the awesome State Variable TPT Filter simply by adding this to ProcessSample:

switch (filterType)
    {
    case Type::lowpass:   return yLP;
    case Type::highpass:  return yHP;
    case Type::bandpass:  return yBP;
    case Type::notch:     return (yLP + yHP);
    case Type::peak:      return (yLP - yHP);
    case Type::lp:        return (yLP + yBP);            // Single poles
    case Type::hp:        return (yHP + yBP);
    case Type::bpN:       return (yBP * R2);            // Non-unity gain filters
    case Type::lowpassN:  return (yLP * R2);
    case Type::highpassN: return (yHP * R2);
    case Type::allpass:   return (inputValue - ((yBP * R2) + (yBP * R2)));
    default:              return yLP;
    }

Happy modulating!