enum filter types, alternate Q calculation

This commit is contained in:
Connor Olding 2014-02-03 15:02:24 -08:00
parent a97baa7779
commit 3efe119c57
5 changed files with 40 additions and 36 deletions

View file

@ -126,7 +126,7 @@ adjust(personal *data, ulong fs) {
c->up[i] = 0; c->up[i] = 0;
for (int i = 0; i < DOWN; i++) for (int i = 0; i < DOWN; i++)
c->down[i] = 0; c->down[i] = 0;
c->filter = biquad_gen(0, 16630, 10, 1, fs*oversample); c->filter = biquad_gen(FILT_PEAKING, 16630, 10, 1, fs*oversample);
biquad_init(&c->filter); biquad_init(&c->filter);
} }
} }

8
crap_eq.h Executable file → Normal file
View file

@ -79,8 +79,8 @@ construct_params(param *params) {
param_reset(&params[1]); param_reset(&params[1]);
sprintf(params[2].name, "Band %i Bandwidth", i + 1); sprintf(params[2].name, "Band %i Bandwidth", i + 1);
params[2].min = 0.0625; params[2].min = 0.0625; // 2^-4 could probably be 2^-3
params[2].max = 8; params[2].max = 8; // 2^3 could probably be 2^2
params[2].scale = SCALE_FLOAT; params[2].scale = SCALE_FLOAT;
params[2].def = DEFAULT_1; params[2].def = DEFAULT_1;
param_reset(&params[2]); param_reset(&params[2]);
@ -102,7 +102,7 @@ adjust(personal *data, param *params, unsigned long fs) {
data->fs = fs; data->fs = fs;
biquad *filters = data->filters[0]; biquad *filters = data->filters[0];
for (int i = 0; i < BANDS; i++) { for (int i = 0; i < BANDS; i++) {
filters[i] = biquad_gen(0, filters[i] = biquad_gen(FILT_PEAKING,
params[0].value, params[1].value, params[2].value, fs); params[0].value, params[1].value, params[2].value, fs);
params += 3; params += 3;
} }
@ -113,7 +113,7 @@ static void
adjust_one(personal *data, param *params, unsigned int index) { adjust_one(personal *data, param *params, unsigned int index) {
float fs = data->fs; float fs = data->fs;
params += index/3*3; params += index/3*3;
data->filters[0][index/3] = biquad_gen(0, data->filters[0][index/3] = biquad_gen(FILT_PEAKING,
params[0].value, params[1].value, params[2].value, fs); params[0].value, params[1].value, params[2].value, fs);
resume(data); resume(data);
} }

View file

@ -69,8 +69,8 @@ pause(personal *data) {
static void static void
adjust(personal *data, unsigned long fs) { adjust(personal *data, unsigned long fs) {
biquad *filters = data->filters[0]; biquad *filters = data->filters[0];
filters[0] = biquad_gen(0, 34.34, +4.6, 1.21, fs); filters[0] = biquad_gen(FILT_PEAKING, 34.34, +4.6, 1.21, fs);
filters[1] = biquad_gen(0, 85.74, -1.2, 1.31, fs); filters[1] = biquad_gen(FILT_PEAKING, 85.74, -1.2, 1.31, fs);
filters[2] = biquad_gen(2, 862.2, -5.5, 1.00, fs); filters[2] = biquad_gen(FILT_HIGHSHELF, 862.2, -5.5, 1.00, fs);
filters[3] = biquad_gen(0, 7496., +3.3, 1.10, fs); filters[3] = biquad_gen(FILT_PEAKING, 7496., +3.3, 1.10, fs);
} }

View file

@ -29,20 +29,21 @@ whitenoise();
static void static void
biquad_init(biquad *bq); biquad_init(biquad *bq);
/* types: TODO: enum typedef enum {
0: peaking FILT_PEAKING,
1: lowshelf FILT_LOWSHELF,
2: highshelf FILT_HIGHSHELF,
3: lowpass FILT_LOWPASS,
4: highpass FILT_HIGHPASS,
5: allpass FILT_ALLPASS,
6: bandpass 1 FILT_BANDPASS,
7: bandpass 2 FILT_BANDPASS_2,
8: notch FILT_NOTCH,
9: gain FILT_GAIN
*/ } filter_t;
static biquad static biquad
biquad_gen(int type, double fc, double gain, double bw, double fs); biquad_gen(filter_t type, double fc, double gain, double bw, double fs);
/* s-plane to z-plane */ /* s-plane to z-plane */
static biquad_interim static biquad_interim

View file

@ -38,29 +38,32 @@ design(double cw, double sw,
} }
static biquad static biquad
biquad_gen(int type, double fc, double gain, double bw, double fs) { biquad_gen(filter_t type, double fc, double gain, double bw, double fs) {
double w0, cw, sw, A, As, Q; double w0, cw, sw, A, As, Q;
w0 = ANGULAR_LIM(fc, fs); w0 = ANGULAR_LIM(fc, fs);
cw = cos(w0); cw = cos(w0);
sw = sin(w0); sw = sin(w0);
A = DB2LIN(gain/2); A = DB2LIN(gain/2);
As = sqrt(A); As = sqrt(A);
Q = 1/(4*sinh(M_LN2/2*bw*w0/sw)); Q = M_SQRT1_2*(1 - (w0/M_PI)*(w0/M_PI))/bw;
//Q = M_SQRT1_2*(1 - SQR(w0/M_PI))/bw;
/* skip = (fabs(A - 1) <= TINY); */ /* skip = (fabs(A - 1) <= TINY); */
/* TODO: use enum for type instead of just int */
biquad_interim bqi; biquad_interim bqi;
if (type == 0) bqi = design(cw,sw, 1, A/Q, 1, 1, 1/A/Q, 1);
if (type == 1) bqi = design(cw,sw, 1, As/Q, A, 1, 1/As/Q, 1/A); #define d(n0,n1,n2,d0,d1,d2) bqi = design(cw,sw,n0,n1,n2,d0,d1,d2)
if (type == 2) bqi = design(cw,sw, A, As/Q, 1, 1/A, 1/As/Q, 1); switch (type) {
if (type == 3) bqi = design(cw,sw, 0, 0, 1, 1, 1/Q, 1); case FILT_PEAKING: d(1, A/Q, 1, 1, 1/A/Q, 1); break;
if (type == 4) bqi = design(cw,sw, 1, 0, 0, 1, 1/Q, 1); case FILT_LOWSHELF: d(1, As/Q, A, 1, 1/As/Q, 1/A); break;
if (type == 5) bqi = design(cw,sw, 1, -1/Q, 1, 1, 1/Q, 1); case FILT_HIGHSHELF: d(A, As/Q, 1, 1/A, 1/As/Q, 1); break;
if (type == 6) bqi = design(cw,sw, 0, 1, 0, 1, 1/Q, 1); case FILT_LOWPASS: d(0, 0, 1, 1, 1/Q, 1); break;
if (type == 7) bqi = design(cw,sw, 0, 1/Q, 0, 1, 1/Q, 1); case FILT_HIGHPASS: d(1, 0, 0, 1, 1/Q, 1); break;
if (type == 8) bqi = design(cw,sw, 1, 0, 1, 1, 1/Q, 1); case FILT_ALLPASS: d(1, -1/Q, 1, 1, 1/Q, 1); break;
if (type == 9) bqi = design(cw,sw, A, A, A, 1/A, 1/A, 1/A); case FILT_BANDPASS: d(0, 1, 0, 1, 1/Q, 1); break;
case FILT_BANDPASS_2: d(0, 1/Q, 0, 1, 1/Q, 1); break;
case FILT_NOTCH: d(1, 0, 1, 1, 1/Q, 1); break;
case FILT_GAIN: d(A, A, A, 1/A, 1/A, 1/A); break;
}
#undef d
double a0r = 1/bqi.a0; double a0r = 1/bqi.a0;