Last active
July 19, 2022 19:05
-
-
Save phkahler/0d34bc446845a9d7fee7e1506d9b2b04 to your computer and use it in GitHub Desktop.
Equalizer (8 band)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
// A simple 8-band EQ. The filters are all first order so there is | |
// lot of overlap in adjacent bands. Never the less this should be | |
// a solid way to shape the tone of an audio signal. | |
// Aiming to eventually put this in OBS, which IMHO needs one. | |
// This is a Work In Progress. | |
// | |
// We will use a set of 7 filters to split a signal s into 8 bands | |
// |<----------------------------- s ----------------------------->| | |
// |<-------------s10------------->|<-------------s11------------->| | |
// |<-----s20----->|<-----s21----->|<-----s22----->|<-----s23----->| | |
// |<-s30->|<-s31->|<-s32->|<-s33->|<-s34->|<-s35->|<-s36->|<-s37->| | |
struct equalizer { | |
// sample frequency | |
float freq; | |
// user/slider gain settings | |
float g[8]; | |
// internal gains for the 7 Low Pass Filters | |
float f1, f2, f3, f4, f5, f6, f7; | |
// odd numbered signals do not require storage across samples | |
float s10, s20, s22, s30, s32, s34, s36; | |
}; | |
void equalizer_set_user_gains(struct equalizer *eq, float gain[8]) | |
{ | |
int i; | |
for (i=0; i<8; i++) | |
{ | |
eq->g[i] = gain[i]; | |
} | |
} | |
// we need the sample frequency and the 7 cutoff frequencies between bands | |
void equalizer_set_frequencies(struct equalizer *eq, float f, | |
float c1, float c2, float c3, float c4, float c5, float c6, float c7) | |
{ | |
eq->freq = f; | |
// Calculate the filter gains (alpha) from cuttoff and sample frequencies | |
eq->f1 = 1.0 - exp(-2*3.14159265*c1/f); | |
eq->f2 = 1.0 - exp(-2*3.14159265*c2/f); | |
eq->f3 = 1.0 - exp(-2*3.14159265*c3/f); | |
eq->f4 = 1.0 - exp(-2*3.14159265*c4/f); | |
eq->f5 = 1.0 - exp(-2*3.14159265*c5/f); | |
eq->f6 = 1.0 - exp(-2*3.14159265*c6/f); | |
eq->f7 = 1.0 - exp(-2*3.14159265*c7/f); | |
} | |
// s is a sample of the input signal, out is the output sample | |
float equalizer_update(struct equalizer *eq, float s) | |
{ | |
float s11, s21, s23, s31, s33, s35, s37; | |
// first LPF / HPF combination | |
eq->s10 += (s - eq->s10)*eq->f4; | |
s11 = s - eq->s10; | |
// second layer of filters | |
eq->s20 += (eq->s10 - eq->s20)*eq->f2; | |
eq->s22 += (s11 - eq->s22)*eq->f6; | |
s21 = eq->s10 - eq->s20; | |
s23 = s11 - eq->s22; | |
// third filter layer | |
eq->s30 += (eq->s20 - eq->s30)*eq->f1; | |
eq->s32 += (s21 - eq->s32)*eq->f3; | |
eq->s34 += (eq->s22 - eq->s34)*eq->f5; | |
eq->s36 += (s23 - eq->s36)*eq->f7; | |
s31 = eq->s20 - eq->s30; | |
s33 = s21 - eq->s32; | |
s35 = eq->s22 - eq->s34; | |
s37 = s23 - eq->s36; | |
// apply pass-band gains and sum | |
float out = eq->s30*eq->g[0] + s31*eq->g[1] + eq->s32*eq->g[2] + s33*eq->g[3]; | |
out += eq->s34*eq->g[4] + s35*eq->g[5] + eq->s36*eq->g[6] + s37*eq->g[7]; | |
return (out); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment