ΣSigmaStudio Ask AI Русский Log in

Calculating coefficients for parametric and peaking EQ on a PC

SigmaDSP & SigmaStudio Leonidus Mar 17, 2021 00:00 3 replies Original on forum ↗
Subscribe
Leonidus Question
Mar 17, 2021 00:00

Hello!

I need to generate coeeficients for peaking EQ on microcontroller. I have seen wiki, but there is no information about peaking EQ calculation. And it's my first question: were I can find information about peaking EQ calculation?

Next step I tryed to change peaking EQ to parametric, because here I found information about it:

wiki.analog.com/.../GeneralEq2ndorder

First of all I write this code on my PC:

#include <iostream>
#include <math.h>
using namespace std;

int32_t SIGMASTUDIOTYPE_FIXPOINT_CONVERT(double value) { return (int32_t)(value * (0x01 << 23)); }

int main(){
double PI = 3.14159265;
double dBgain = 1.00;
double frequency = 50.00;
double sampleRate = 48000.00;
double Q = 1.41;
double bandwidth = frequency/Q;
double A = pow(10, dBgain / 40);
double omega = 2 * PI * frequency / sampleRate;
double alpha = sin(omega) / (2 *A * Q);
double gainLinear = pow(10, (dBgain / 20));

double a0 = 1 + alpha/A;
double a1 = 2 * cos(omega);
double a2 = 1 - alpha/A;
double b0 = (1 + alpha * A) * gainLinear;
double b1 = (2 * cos(omega)) * gainLinear;
double b2 = (1 - alpha * A) * gainLinear;

int B0 = SIGMASTUDIOTYPE_FIXPOINT_CONVERT(b0 / a0);
int B1 = SIGMASTUDIOTYPE_FIXPOINT_CONVERT(b1 / a0);
int B2 = SIGMASTUDIOTYPE_FIXPOINT_CONVERT(b2 / a0);
int A1 = SIGMASTUDIOTYPE_FIXPOINT_CONVERT(a1 / a0);
int A2 = SIGMASTUDIOTYPE_FIXPOINT_CONVERT(a2 / a0);
printf(" B0 = %X \n B1 = %X \n B2 = %X \n A1 = %X \n A2 = %X \n", B0, B1, B2, A1, A2);
printf(" B0 = %f \n B1 = %f \n B2 = %f \n A1 = %f \n A2 = %f \n", b0/a0, b1 / a0, b2 / a0, a1 / a0, a2 / a0);
}

Result of my programm:

B0 = 8FA78F
B1 = 11EA33D
B2 = 8EFD40
A1 = FF7751
A2 = 7F78B7

In float:
B0 = 1.122301
B1 = 2.239357
B2 = 1.117104
A1 = 1.995829
A2 = 0.995872

Result of SigmaStudio:

0x00, 0xFE, 0xCF, 0xF5,
0xFE, 0x01, 0x21, 0x5D,
0x01, 0x00, 0x11, 0x7C,
0xFF, 0x01, 0x1E, 0x8F,
0x01, 0xFE, 0xDE, 0xA3,

I found that I need to normalize coefficients (devide by a0) and use SIGMASTUDIOTYPE_FIXPOINT_CONVERT.

I use ADAU 1452.

And it's my second question: why values from my programm and from SigmaStudio so different?

Audio Signal Processors

adau1452

coefficients

adau1452 sigmastudio

SigmaDSP Audio Processors

unknown.png-350x50.png
unknown.png-350x50.png
KJBob Reply
Mar 17, 2021 00:00

Hello Leonidus,

I've been using the spreadsheet attached below to compute 2nd Order IIR coefficients. Originally by the legendary BrettG, I have since expanded it to cover more filter types. You'll find parametric at its far left, and peaking at the far right. To check it I had it compute coefficients for a peaking filter of gain 20 dB, 50 Hz center frequency, and Q of 1,4142. The resulting coefficients are already normalized, and can be typed directly into the IIR Coefficient dialog in the General 2nd Order Filter:

The parametric formulas are more complex than the peaking ones. In the spreadsheet, gain refers to the filer's overall dB gain (as an amplifier), while boost describes the peak or dip of its curve (that is, the position of the GUI slider). Here's the coefficients for a 50 Hz, Q = 1.4142, unity gain, boost =1 parametric filter:

You can extract the cell formulas from the spreadsheet for your C code.

Best regards,

Bob

1682.1st-2nd-Order_IIR_Coefficient_Calc.zip

8446.filter.png
8446.filter.png
2161.filter2.png
2161.filter2.png
Leonidus Reply
Mar 18, 2021 00:00

Big thanks for the formula!)))

Now I try to use: Filters -> Second order -> Single Precision -> Clickless HW Slew -> Text-In Eq (peaking, Freq 50, Q 1.41, Gain 1)

But I have else one question... When I try to convert float values to ADAU fixed point format, I can't achieve similar values to the SigmaStudio calculations..

I try to implement it by this functions:

1.

int32_t SIGMASTUDIOTYPE_FIXPOINT_CONVERT(double value) { return (int32_t)(value * (0x01 << 23)); }

and, as guided here, by this:

2.

int To523(float param_dec, char* param_hex){
long param223;
long param227;
//multiply decimal number by 2^23
param223 = param_dec * (1 << 23);
//convert to positive binary
param227 = param223 + (1 << 27);
param_hex[3] = (char)param227; //get char 3 (LSBs) of parameter value
param_hex[2] = (char)(param227 >> 8); //get char 2 of parameter value
param_hex[1] = (char)(param227 >> 16); //get char 1 of parameter value
//get char 0 (MSBs) of parameter value
param_hex[0] = (char)(param227 >> 24);
//invert sign bit to get correct sign
param_hex[0] = param_hex[0] ^ 0x08;
// in integer format:
int rez = param_hex[0] << 24 | param_hex[1] << 16 | param_hex[2] << 8 | param_hex[3];
return rez;
}

But for my case (Q = 1.41, Fs = 48000, gain = 1, f0 = 50) rezults from SigmaStudio still (peaking EQ 2nd order)

0xFF, 0xFF, 0x55, 0xBB,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xAA, 0x45,
0xFF, 0x01, 0x2F, 0x81,
0x01, 0xFE, 0xCD, 0xB2,

and from functions (naturally similar) :

1.

B0 = 5522
B1 = 0
B2 = FFFFAADE
A1 = FF66D9
A2 = 7F683F

2.

5522
0
FFFFFFDE
FFFFFFD9
7F6840

Maybe you still know how to correctly convert the coefficients to hex?)

Leonidus Reply
Mar 18, 2021 00:00

I found solution.

Correct transform from float to hex:

int32_t SIGMASTUDIOTYPE_FIXPOINT_CONVERT(double value) { return (int32_t)(value * (double)((int32_t)0x01 << 24)); }

correct transform from hex to float:

float CONVERT_TO_FLOAT(int32_t value) {
return float(int32_t((value & 0x8000000) ? (value | 0xF0000000) : value)) / (int32_t(1) << 24);
}

Byte order in .params file is direct, i.e. you do not need to rearrange anything.

Example:

you have

Parameter Value = -0.995627462863922
Parameter Data : 0xFF , 0x01 , 0x1E , 0x8F ,

float val = CONVERT_TO_FLOAT(0xFF011E8F);
printf("%f\n", val);
int newVal = SIGMASTUDIOTYPE_FIXPOINT_CONVERT(val);
printf("%X\n", newVal);
val = CONVERT_TO_FLOAT(newVal);
printf("%f\n", val);

You achieve equivalent values. Big thank you for the excel formulas again, they are very similar to SigmaStudio's calculations.