MCUdude / SigmaDSP

A versatile Arduino library for interfacing with the ADAU1401, ADAU1701 and ADAU1702 audio DSPs
GNU Lesser General Public License v3.0
171 stars 36 forks source link

Real time variable frequency adjustment of secondOrderEQ blocks #28

Closed SitrucL closed 2 years ago

SitrucL commented 2 years ago

Hi all,

I've been attempting to adjust the frequency of the secondOrderEQ instance using a potentiometer however, doing so causes the DSP to not output anything other than a high pitched sound on one of the four DAC outputs. I'm aware that the MCU is having to perform several calculations (found within SigmaDSP::EQsecondOrder of SigmaDSP.cpp) for the coefficients but after logging out the results, it looks as though these are coming through as expected.

For context, I've got three 2nd order EQ blocks feeding into one another to form a 6th order eq

 dsp.EQsecondOrder(MOD_LOW_A_ALG0_STAGE0_B0_ADDR, Low_A);
 dsp.EQsecondOrder(MOD_LOW_A_2_ALG0_STAGE0_B0_ADDR, Low_A_2);
 dsp.EQsecondOrder(MOD_LOW_A_3_ALG0_STAGE0_B0_ADDR, Low_A_3);

image

When I use a fixed value for the frequency rather than the potentiometer value, things work as expected however I would ideally like to have the ability to adjust the frequency of the blocks in real time. Any thoughts and suggestions as to how this might be possible or what's causing my current issue?

Thanks in advance

MCUdude commented 2 years ago

Hi! Can you post the complete code (typically the contents of the INO file)? If it works with fixed values it may be a problem with your code and not necessarily the library.

SitrucL commented 2 years ago

Hi, I've deviated quite drastically from the original project structure and no longer have a .ino file but instead a collection of .cpp files, here is the one I'm using for my first EQ band

// Include generated parameter file

#include "EQ_band_A.h"

secondOrderEQ High_A;
secondOrderEQ High_A_2;
secondOrderEQ High_A_3;
secondOrderEQ Low_A;
secondOrderEQ Low_A_2;
secondOrderEQ Low_A_3;

int eqBandA_vol;
int prev_eqBandA_vol;
int max_crossover_A = 90;
int min_crossover_A = 150;
int crossover_A = 90;
int low_end_A = 25;

void setupEQBandA()
{
    // Intialise High A
    High_A.filterType = parameters::filterType::highpass;
    High_A.freq = low_end_A;
    High_A.state = parameters::state::on;
    High_A.Q = 0.51763809;

    // Intialise High A_2
    High_A_2.filterType = parameters::filterType::highpass;
    High_A_2.freq = low_end_A;
    High_A_2.state = parameters::state::on;
    High_A_2.Q = 0.70710678;

    // Intialise High A_3
    High_A_3.filterType = parameters::filterType::highpass;
    High_A_3.freq = low_end_A;
    High_A_3.state = parameters::state::on;
    High_A_3.Q = 1.9318517;

    dsp.EQsecondOrder(MOD_HIGH_A_ALG0_STAGE0_B0_ADDR, High_A);
    dsp.EQsecondOrder(MOD_HIGH_A_2_ALG0_STAGE0_B0_ADDR, High_A_2);
    dsp.EQsecondOrder(MOD_HIGH_A_3_ALG0_STAGE0_B0_ADDR, High_A_3);

    // Intialise Low A_3
    Low_A_3.filterType = parameters::filterType::lowpass;
    Low_A_3.freq = crossover_A;
    Low_A_3.state = parameters::state::on;
    Low_A_3.Q = 0.51763809;

    // Intialise Low A_2
    Low_A_2.filterType = parameters::filterType::lowpass;
    Low_A_2.freq = crossover_A;
    Low_A_2.state = parameters::state::on;
    Low_A_2.Q = 0.70710678;

    // Intialise Low A
    Low_A.filterType = parameters::filterType::lowpass;
    Low_A.freq = crossover_A;
    Low_A.state = parameters::state::on;
    Low_A.Q = 1.9318517;

    dsp.EQsecondOrder(MOD_LOW_A_ALG0_STAGE0_B0_ADDR, Low_A);
    dsp.EQsecondOrder(MOD_LOW_A_2_ALG0_STAGE0_B0_ADDR, Low_A_2);
    dsp.EQsecondOrder(MOD_LOW_A_3_ALG0_STAGE0_B0_ADDR, Low_A_3);

    dsp.volume(MOD_MULTIPLE1_ALG0_GAIN1940ALGNS1_ADDR, eqBandA_vol); // (First volume slider address, dB value, optional slew value)
    Serial.println(F("--- 1st eq filter on! ---"));
}

void updateEQBandA(int value, char param)
{
    switch (param)
    {
    case 'f':
        Low_A.freq = crossover_A;
        Low_A_2.freq = crossover_A;
        Low_A_3.freq = crossover_A;
        Serial.println(F("--- 1st eq filter changed --- \n"));
        dsp.EQsecondOrder(MOD_LOW_A_ALG0_STAGE0_B0_ADDR, Low_A);
        dsp.EQsecondOrder(MOD_LOW_A_2_ALG0_STAGE0_B0_ADDR, Low_A_2);
        dsp.EQsecondOrder(MOD_LOW_A_3_ALG0_STAGE0_B0_ADDR, Low_A_3);
        break;
    case 'v':
        dsp.volume(MOD_MULTIPLE1_ALG0_GAIN1940ALGNS1_ADDR, value);
        break;
    case 'm':
        dsp.mute(MOD_MUTE_A_MUTENOSLEWALG1MUTE_ADDR, value);
    default:
        break;
    }
}

Then I have a main.cpp which simply reads the values of the potentiometers, checks for any changes and passes it to the relevant places like so:

int x_over_pot_A = floatMap(analogRead(crossover_A_pot), 0, max_potentiometer_val, min_crossover_A, max_crossover_A);

I'm using the exact same logic for adjusting the volume|(gain) which you can see in the code block for EQ_band_A and this works completely as expected.

I can try to zip up my entire project and post it here if github allows - EDIT github didnt allow me upload the zip for some reason

SitrucL commented 2 years ago

Apologies, I had made some unnecessary adjustments to the coefficient calculations within SigmaDSP.cpp which was the cause of the problem

MCUdude commented 2 years ago

No worries! Great to hear you figured it out. Thanks for using my library!