OWL DSP Library compiler Problem

Im new in Programing OWL. I try to compile this code:

#include "Patch.h"
#include "BiquadFilter.h"

class Patch3 : public Patch
{

private:
    BiquadFilter* filter;

public:

    Patch3()
    {
        registerParameter(PARAMETER_A, "fc");
        registerParameter(PARAMETER_B, "q");
        filter = BiquadFilter::create(2);
    }

    ~Patch3()
    {
        BiquadFilter::destroy(filter);
    }

    void processAudio(AudioBuffer &buffer)
    {
        FloatArray buf = buffer.getSamples(LEFT_CHANNEL);
        float pa = getParameterValue(PARAMETER_A) * 20000;
        float pb = getParameterValue(PARAMETER_A);
        filter->setLowPass(pa, pb);
        filter->process(buf);
    }
};

But on compile time i become he error:

/opt/OwlProgram.online/Tools/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: /tmp/owl/owl-build-qZSMEr/PatchProgram.o (symbol from plugin): in function onMidiCallback(unsigned char, unsigned char, unsigned char, unsigned char)’: (.text+0x0): multiple definition of FilterStage::BESSEL_Q'; /tmp/owl/owl-build-qZSMEr/Patch3.o (symbol from plugin):(.text+0x0): first defined here /opt/OwlProgram.online/Tools/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: /tmp/owl/owl-build-qZSMEr/PatchProgram.o (symbol from plugin): in function onMidiCallback(unsigned char, unsigned char, unsigned char, unsigned char)’: (.text+0x0): multiple definition of FilterStage::BUTTERWORTH_Q'; /tmp/owl/owl-build-qZSMEr/Patch3.o (symbol from plugin):(.text+0x0): first defined here /opt/OwlProgram.online/Tools/gcc-arm-none-eabi-9-2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld: /tmp/owl/owl-build-qZSMEr/PatchProgram.o (symbol from plugin): in function onMidiCallback(unsigned char, unsigned char, unsigned char, unsigned char)’: (.text+0x0): multiple definition of FilterStage::SALLEN_KEY_Q'; /tmp/owl/owl-build-qZSMEr/Patch3.o (symbol from plugin):(.text+0x0): first defined here collect2: error: ld returned 1 exit status make[1]: *** [/tmp/owl/owl-build-qZSMEr/patch.elf] Error 1 make: *** [patch] Error 2 ERROR: Patch build failed.

is there enybody who see the error that i made?

/Robert

Hi Robert,

OWL does a bit magic behind the scene, so you should name your patches like “FooPatch” instead of just “Foo”. I think this is the only problem here, with that renaming it compiles fine: https://www.rebeltech.org/patch-library/patch/Patch3

There’s a small bug here:

        float pb = getParameterValue(PARAMETER_A);

it was obviously meant to use PARAMETER_B. Also, generally for frequency we want exponential behavior instead of linear. There are some methods in VoltsPerOctave class that you could use for scaling.

Btw, unless you need to use specifically biquad filter for some reason, you may get better results from the SVF in StateVariableFilter.h for processing audio.

Cheers, Stas

Hi Stas,

thanks for your help. it was verry usefull.

I take in my mind:

  • The C++ File must be named like the Patch with the postfix “Patch”. (is the patch name xyz then the class must named xyzPatch)
  • The c++ File with the class must be with postfix hpp and not with cpp. Else the file looks like loaded doubled as header and as cpp.

The frequence at the Bicuadfilter in not in Hz. It seems to be a Percentage Value so it works with no mulitpikation by Filter open Hz.

    float pa = getParameterValue(PARAMETER_A);
    float pb = getParameterValue(PARAMETER_B);
    filter->setLowPass(pa, pb);
    filter->process(buf,buf);

Thanks

It should be using Hertz for frequency cutoff according to docs OpenWareLaboratory: BiquadFilter.h Source File , are you sure that you’re not looking at FilterStage class that uses omega (frequency * PI / samplerate)?

There were some experiments for changing oscillators to use normalized frequency (in 0…1 range), but I don’t remember @mars changing this for biquads.

An old version of BiquadFilter used cutoff frequencies that were normalised to 1/2 Nyquist, mirroring the Matlab convention. This was quite easy to work with in simple cases, but using normalised frequencies throughout the library didn’t seem like a great idea and so Biquad filter was changed to take frequency arguments in Hertz. For this to work you need to pass the sample rate in the create() method, which I think is what is missing in your case.

Change your initialiser to

        filter = BiquadFilter::create(getSampleRate(), 2);

and then pass frequency in Hz to filter->setLowPass()

The API saw a big rewrite fairly recently and most of the examples are still out of date.

The best up-to-date references are here:

https://www.rebeltech.org/docs/