1 #ifndef ORFANIDIS_EQ_H_
2 #define ORFANIDIS_EQ_H_
9 namespace orfanidis_eq
{
12 typedef double eq_single_t
;
13 typedef double eq_double_t
;
14 //NOTE: the default float type usage
15 //can have shortage of precision
25 static const char *get_eq_text(filter_type type
) {
28 return "not initialized";
43 invalid_input_data_error
,
48 static const eq_double_t pi
= 3.1415926535897932384626433832795;
49 static const unsigned int fo_section_order
= 4;
52 static const int max_base_gain_db
= 0;
53 static const int min_base_gain_db
= -60;
54 static const int butterworth_band_gain_db
= -3;
55 static const int chebyshev1_band_base_gain_db
= -6;
56 static const int chebyshev2_band_base_gain_db
= -40;
57 static const int eq_min_max_gain_db
= 46;
60 static const eq_double_t lowest_grid_center_freq_hz
= 31.25;
61 static const eq_double_t bands_grid_center_freq_hz
= 1000;
62 static const eq_double_t lowest_audio_freq_hz
= 20;
63 static const eq_double_t highest_audio_freq_hz
= 20000;
66 static const unsigned int default_eq_band_filters_order
= 4; //>2
67 static const eq_double_t default_sample_freq_hz
= 48000;
69 //Precomputed Eq (eq2) config constants
70 static const eq_double_t p_eq_min_max_gain_db
= 40;
71 static const eq_double_t p_eq_gain_step_db
= 1;
72 static const eq_double_t common_base_gain_db
= 3;
73 static const eq_double_t p_eq_default_gain_db
= 0;
76 static const char* eq_version
= "0.01";
79 //------------ Conversion functions class ------------
83 std::vector
<eq_double_t
> lin_gains
;
85 int lin_gains_index(eq_double_t x
) {
87 if((x
>= -db_min_max
) && (x
< db_min_max
- 1))
88 return db_min_max
+ int_x
;
96 conversions(int min_max
) {
98 //Update table (vector elements) for fast conversions
100 while(step
<= min_max
)
101 lin_gains
.push_back(db_2_lin(step
++));
104 inline eq_double_t
fast_db_2_lin(eq_double_t x
) {
105 int int_part
= (int)x
;
106 eq_double_t frac_part
= x
- int_part
;
107 return lin_gains
[lin_gains_index(int_part
)]*(1-frac_part
) +
108 (lin_gains
[lin_gains_index(int_part
+ 1)])*frac_part
;
111 inline eq_double_t
fast_lin_2_db(eq_double_t x
) {
112 if((x
>= lin_gains
[0]) && (x
< lin_gains
[lin_gains
.size() - 1])) {
113 for (unsigned int i
= 0; i
< lin_gains
.size() - 2; i
++)
114 if((x
>= lin_gains
[i
]) && (x
< lin_gains
[i
+ 1])) {
115 int int_part
= i
- db_min_max
;
116 eq_double_t frac_part
= x
- (int)(x
);
117 return int_part
+ frac_part
;
123 inline static eq_double_t
db_2_lin(eq_double_t x
) {
124 return pow(10, x
/20);
127 inline static eq_double_t
lin_2_db(eq_double_t x
) {
131 inline static eq_double_t
rad_2_hz(eq_double_t x
, eq_double_t fs
) {
135 inline static eq_double_t
hz_2_rad(eq_double_t x
, eq_double_t fs
) {
140 //------------ Band freq's structure ------------
146 eq_double_t min_freq
;
147 eq_double_t center_freq
;
148 eq_double_t max_freq
;
150 band_freqs(eq_double_t f1
, eq_double_t f0
, eq_double_t f2
):
151 min_freq(f1
), center_freq(f0
), max_freq(f2
){}
156 //------------ Frequency grid class ------------
159 std::vector
<band_freqs
> freqs_
;
163 freq_grid(const freq_grid
& fg
){this->freqs_
= fg
.freqs_
;}
166 eq_error_t
set_band(eq_double_t fmin
, eq_double_t f0
, eq_double_t fmax
) {
168 return add_band(fmin
, f0
, fmax
);
172 eq_error_t
add_band(eq_double_t fmin
, eq_double_t f0
, eq_double_t fmax
) {
173 if(fmin
< f0
&& f0
< fmax
)
174 freqs_
.push_back(band_freqs(fmin
, f0
, fmax
));
176 return invalid_input_data_error
;
180 //f0, deltaf = fmax - fmin
181 eq_error_t
add_band(eq_double_t f0
, eq_double_t df
) {
184 eq_double_t fmin
= f0
- df
/2;
185 eq_double_t fmax
= f0
+ df
/2;
186 freqs_
.push_back(band_freqs(fmin
, f0
, fmax
));
189 return invalid_input_data_error
;
193 eq_error_t
set_5_bands(eq_double_t center_freq
= bands_grid_center_freq_hz
) {
195 if(lowest_audio_freq_hz
< center_freq
&&
196 center_freq
< highest_audio_freq_hz
) {
198 //Find lowest center frequency in band
199 eq_double_t lowest_center_freq
= center_freq
;
200 while(lowest_center_freq
> lowest_grid_center_freq_hz
)
201 lowest_center_freq
/=4.0;
202 if(lowest_center_freq
< lowest_grid_center_freq_hz
)
203 lowest_center_freq
*=4.0;
206 eq_double_t f0
= lowest_center_freq
;
207 for(unsigned int i
= 0; i
< 5 ; i
++) {
208 freqs_
.push_back(band_freqs(f0
/2, f0
, f0
*2));
213 return invalid_input_data_error
;
217 eq_error_t
set_10_bands(eq_double_t center_freq
= bands_grid_center_freq_hz
) {
219 if(lowest_audio_freq_hz
< center_freq
&&
220 center_freq
< highest_audio_freq_hz
) {
222 //Find lowest center frequency in band
223 eq_double_t lowest_center_freq
= center_freq
;
224 while(lowest_center_freq
> lowest_grid_center_freq_hz
)
225 lowest_center_freq
/=2;
226 if(lowest_center_freq
< lowest_grid_center_freq_hz
)
227 lowest_center_freq
*=2;
230 eq_double_t f0
= lowest_center_freq
;
231 for(unsigned int i
= 0; i
< 10; i
++) {
232 freqs_
.push_back(band_freqs(f0
/pow(2,0.5), f0
, f0
*pow(2,0.5)));
237 return invalid_input_data_error
;
241 eq_error_t
set_20_bands(eq_double_t center_freq
= bands_grid_center_freq_hz
) {
243 if(lowest_audio_freq_hz
< center_freq
&&
244 center_freq
< highest_audio_freq_hz
) {
246 //Find lowest center frequency in band
247 eq_double_t lowest_center_freq
= center_freq
;
248 while(lowest_center_freq
> lowest_audio_freq_hz
)
249 lowest_center_freq
/=pow(2,0.5);
250 if(lowest_center_freq
< lowest_audio_freq_hz
)
251 lowest_center_freq
*=pow(2,0.5);
254 eq_double_t f0
= lowest_center_freq
;
255 for(unsigned int i
= 0; i
< 20; i
++) {
256 freqs_
.push_back(band_freqs(f0
/pow(2,0.25),
257 f0
, f0
*pow(2,0.25)));
262 return invalid_input_data_error
;
266 eq_error_t
set_30_bands(eq_double_t center_freq
= bands_grid_center_freq_hz
) {
268 if(lowest_audio_freq_hz
< center_freq
&&
269 center_freq
< highest_audio_freq_hz
) {
271 //Find lowest center frequency in band
272 eq_double_t lowest_center_freq
= center_freq
;
273 while(lowest_center_freq
> lowest_audio_freq_hz
)
274 lowest_center_freq
/=pow(2.0,1.0/3.0);
275 if(lowest_center_freq
< lowest_audio_freq_hz
)
276 lowest_center_freq
*=pow(2.0,1.0/3.0);
279 eq_double_t f0
= lowest_center_freq
;
280 for(unsigned int i
= 0; i
< 30; i
++) {
281 freqs_
.push_back(band_freqs(f0
/pow(2.0,1.0/6.0),
282 f0
, f0
*pow(2.0,1.0/6.0)));
283 f0
*= pow(2,1.0/3.0);
287 return invalid_input_data_error
;
291 unsigned int get_number_of_bands(){return freqs_
.size();}
293 std::vector
<band_freqs
> get_freqs(){return freqs_
;}
295 unsigned int get_freq(unsigned int number
) {
296 if(number
< freqs_
.size())
297 return freqs_
[number
].center_freq
;
302 unsigned int get_rounded_freq(unsigned int number
) {
303 if(number
< freqs_
.size()) {
304 unsigned int freq
= freqs_
[number
].center_freq
;
307 else if(freq
>= 100 && freq
< 1000) {
308 unsigned int rest
= freq
%10;
312 return freq
- rest
+ 10;
314 else if(freq
>= 1000 && freq
< 10000) {
315 unsigned int rest
= freq
%100;
319 return freq
- rest
+ 100;
321 else if(freq
>= 10000) {
322 unsigned int rest
= freq
%1000;
326 return freq
- rest
+ 1000;
333 //------------ Forth order sections ------------
336 eq_single_t b0
; eq_single_t b1
; eq_single_t b2
; eq_single_t b3
; eq_single_t b4
;
337 eq_single_t a0
; eq_single_t a1
; eq_single_t a2
; eq_single_t a3
; eq_single_t a4
;
339 eq_single_t numBuf
[fo_section_order
];
340 eq_single_t denumBuf
[fo_section_order
];
342 inline eq_single_t
df1_fo_process(eq_single_t in
) {
345 out
+= (b1
*numBuf
[0] - denumBuf
[0]*a1
);
346 out
+= (b2
*numBuf
[1] - denumBuf
[1]*a2
);
347 out
+= (b3
*numBuf
[2] - denumBuf
[2]*a3
);
348 out
+= (b4
*numBuf
[3] - denumBuf
[3]*a4
);
350 numBuf
[3] = numBuf
[2];
351 numBuf
[2] = numBuf
[1];
352 numBuf
[1] = numBuf
[0];
355 denumBuf
[3] = denumBuf
[2];
356 denumBuf
[2] = denumBuf
[1];
357 denumBuf
[1] = denumBuf
[0];
365 b0
= 1; b1
= 0; b2
= 0; b3
= 0; b4
= 0;
366 a0
= 1; a1
= 0; a2
= 0; a3
= 0; a4
= 0;
368 for(unsigned int i
= 0; i
< fo_section_order
; i
++) {
374 virtual ~fo_section(){}
376 eq_single_t
process(eq_single_t in
) {
377 return df1_fo_process(in
);
380 virtual fo_section
get() {
385 class butterworth_fo_section
: public fo_section
{
386 butterworth_fo_section(){}
387 butterworth_fo_section(butterworth_fo_section
&){}
389 butterworth_fo_section(eq_double_t beta
,
390 eq_double_t s
, eq_double_t g
, eq_double_t g0
,
391 eq_double_t D
, eq_double_t c0
) {
392 b0
= (g
*g
*beta
*beta
+ 2*g
*g0
*s
*beta
+ g0
*g0
)/D
;
393 b1
= -4*c0
*(g0
*g0
+ g
*g0
*s
*beta
)/D
;
394 b2
= 2*(g0
*g0
*(1 + 2*c0
*c0
) - g
*g
*beta
*beta
)/D
;
395 b3
= -4*c0
*(g0
*g0
- g
*g0
*s
*beta
)/D
;
396 b4
= (g
*g
*beta
*beta
- 2*g
*g0
*s
*beta
+ g0
*g0
)/D
;
399 a1
= -4*c0
*(1 + s
*beta
)/D
;
400 a2
= 2*(1 + 2*c0
*c0
- beta
*beta
)/D
;
401 a3
= -4*c0
*(1 - s
*beta
)/D
;
402 a4
= (beta
*beta
- 2*s
*beta
+ 1)/D
;
405 fo_section
get() {return *this;}
408 class chebyshev_type1_fo_section
: public fo_section
{
409 chebyshev_type1_fo_section(){}
410 chebyshev_type1_fo_section(chebyshev_type1_fo_section
&){}
412 chebyshev_type1_fo_section(eq_double_t a
,
413 eq_double_t c
, eq_double_t tetta_b
,
414 eq_double_t g0
, eq_double_t s
, eq_double_t b
,
415 eq_double_t D
, eq_double_t c0
) {
416 b0
= ((b
*b
+ g0
*g0
*c
*c
)*tetta_b
*tetta_b
+ 2*g0
*b
*s
*tetta_b
+ g0
*g0
)/D
;
417 b1
= -4*c0
*(g0
*g0
+ g0
*b
*s
*tetta_b
)/D
;
418 b2
= 2*(g0
*g0
*(1 + 2*c0
*c0
) - (b
*b
+ g0
*g0
*c
*c
)*tetta_b
*tetta_b
)/D
;
419 b3
= -4*c0
*(g0
*g0
- g0
*b
*s
*tetta_b
)/D
;
420 b4
= ((b
*b
+ g0
*g0
*c
*c
)*tetta_b
*tetta_b
- 2*g0
*b
*s
*tetta_b
+ g0
*g0
)/D
;
423 a1
= -4*c0
*(1 + a
*s
*tetta_b
)/D
;
424 a2
= 2*(1 + 2*c0
*c0
- (a
*a
+ c
*c
)*tetta_b
*tetta_b
)/D
;
425 a3
= -4*c0
*(1 - a
*s
*tetta_b
)/D
;
426 a4
= ((a
*a
+ c
*c
)*tetta_b
*tetta_b
- 2*a
*s
*tetta_b
+ 1)/D
;
429 fo_section
get() {return *this;}
432 class chebyshev_type2_fo_section
: public fo_section
{
433 chebyshev_type2_fo_section(){}
434 chebyshev_type2_fo_section(chebyshev_type2_fo_section
&){}
436 chebyshev_type2_fo_section(eq_double_t a
,
437 eq_double_t c
, eq_double_t tetta_b
,
438 eq_double_t g
, eq_double_t s
, eq_double_t b
,
439 eq_double_t D
, eq_double_t c0
) {
440 b0
= (g
*g
*tetta_b
*tetta_b
+ 2*g
*b
*s
*tetta_b
+ b
*b
+ g
*g
*c
*c
)/D
;
441 b1
= -4*c0
*(b
*b
+ g
*g
*c
*c
+ g
*b
*s
*tetta_b
)/D
;
442 b2
= 2*((b
*b
+ g
*g
*c
*c
)*(1 + 2*c0
*c0
) - g
*g
*tetta_b
*tetta_b
)/D
;
443 b3
= -4*c0
*(b
*b
+ g
*g
*c
*c
- g
*b
*s
*tetta_b
)/D
;
444 b4
= (g
*g
*tetta_b
*tetta_b
- 2*g
*b
*s
*tetta_b
+ b
*b
+ g
*g
*c
*c
)/D
;
447 a1
= -4*c0
*(a
*a
+ c
*c
+ a
*s
*tetta_b
)/D
;
448 a2
= 2*((a
*a
+ c
*c
)*(1 + 2*c0
*c0
) - tetta_b
*tetta_b
)/D
;
449 a3
= -4*c0
*(a
*a
+ c
*c
- a
*s
*tetta_b
)/D
;
450 a4
= (tetta_b
*tetta_b
- 2*a
*s
*tetta_b
+ a
*a
+ c
*c
)/D
;
453 fo_section
get() {return *this;}
456 //------------ Bandpass filters ------------
460 virtual ~bp_filter(){}
462 virtual eq_single_t
process(eq_single_t in
) = 0;
465 class butterworth_bp_filter
: public bp_filter
{
467 std::vector
<fo_section
> sections_
;
469 butterworth_bp_filter(){}
471 butterworth_bp_filter(butterworth_bp_filter
& f
) {
472 this->sections_
= f
.sections_
;
475 butterworth_bp_filter(unsigned int N
,
476 eq_double_t w0
, eq_double_t wb
,
477 eq_double_t G
, eq_double_t Gb
, eq_double_t G0
) {
478 //Case if G == 0 : allpass
479 if(G
== 0 && G0
== 0) {
480 sections_
.push_back(fo_section());
484 //Get number of analog sections
485 unsigned int r
= N
%2;
486 unsigned int L
= (N
- r
)/2;
488 //Convert gains to linear scale
489 G
= conversions::db_2_lin(G
);
490 Gb
= conversions::db_2_lin(Gb
);
491 G0
= conversions::db_2_lin(G0
);
493 eq_double_t epsilon
= pow(((eq_double_t
)(G
*G
- Gb
*Gb
))/
494 (Gb
*Gb
- G0
*G0
),0.5);
495 eq_double_t g
= pow(((eq_double_t
)G
),1.0/((eq_double_t
)N
));
496 eq_double_t g0
= pow(((eq_double_t
)G0
),1.0/((eq_double_t
)N
));
497 eq_double_t beta
= pow(((eq_double_t
)epsilon
), -1.0/((eq_double_t
)N
))*
500 eq_double_t c0
= cos(w0
);
502 if (w0
== pi
/2) c0
=0;
503 if (w0
== pi
) c0
=- 1;
505 //Calculate every section
506 for(unsigned int i
= 1; i
<= L
; i
++) {
507 eq_double_t ui
= (2.0*i
-1)/N
;
508 eq_double_t si
= sin(pi
*ui
/2.0);
510 eq_double_t Di
= beta
*beta
+ 2*si
*beta
+ 1;
513 (butterworth_fo_section(beta
, si
, g
, g0
, Di
, c0
));
517 ~butterworth_bp_filter(){}
519 static eq_single_t
compute_bw_gain_db(eq_single_t gain
) {
520 eq_single_t bw_gain
= 0;
522 bw_gain
= gain
+ common_base_gain_db
;
523 else if(gain
> -6 && gain
< 6)
526 bw_gain
= gain
- common_base_gain_db
;
531 virtual eq_single_t
process(eq_single_t in
) {
534 //Process FO sections in serial connection
535 for(unsigned int i
= 0; i
< sections_
.size(); i
++) {
536 p1
= sections_
[i
].process(p0
);
544 class chebyshev_type1_bp_filter
: public bp_filter
{
546 std::vector
<fo_section
> sections_
;
548 chebyshev_type1_bp_filter(){}
550 chebyshev_type1_bp_filter(unsigned int N
,
551 eq_double_t w0
, eq_double_t wb
,
552 eq_double_t G
, eq_double_t Gb
, eq_double_t G0
) {
553 //Case if G == 0 : allpass
554 if(G
== 0 && G0
== 0) {
555 sections_
.push_back(fo_section());
559 //Get number of analog sections
560 unsigned int r
= N
%2;
561 unsigned int L
= (N
- r
)/2;
563 //Convert gains to linear scale
564 G
= conversions::db_2_lin(G
);
565 Gb
= conversions::db_2_lin(Gb
);
566 G0
= conversions::db_2_lin(G0
);
568 eq_double_t epsilon
= pow((eq_double_t
)(G
*G
- Gb
*Gb
)/
569 (Gb
*Gb
- G0
*G0
),0.5);
570 eq_double_t g0
= pow((eq_double_t
)(G0
),1.0/N
);
572 pow(1.0/epsilon
+ pow(1 + pow(epsilon
,-2.0),0.5),1.0/N
);
574 pow(G
/epsilon
+ Gb
*pow(1 + pow(epsilon
,-2.0),0.5),1.0/N
);
575 eq_double_t a
= 0.5*(alfa
- 1.0/alfa
);
576 eq_double_t b
= 0.5*(beta
- g0
*g0
*(1/beta
));
577 eq_double_t tetta_b
= tan(wb
/2);
579 eq_double_t c0
= cos(w0
);
581 if (w0
== pi
/2) c0
=0;
582 if (w0
== pi
) c0
=- 1;
584 //Calculate every section
585 for(unsigned int i
= 1; i
<= L
; i
++) {
586 eq_double_t ui
= (2.0*i
-1.0)/N
;
587 eq_double_t ci
= cos(pi
*ui
/2.0);
588 eq_double_t si
= sin(pi
*ui
/2.0);
590 eq_double_t Di
= (a
*a
+ ci
*ci
)*tetta_b
*tetta_b
+
591 2.0*a
*si
*tetta_b
+ 1;
593 chebyshev_type1_fo_section(a
, ci
, tetta_b
, g0
, si
, b
, Di
, c0
));
598 ~chebyshev_type1_bp_filter(){}
600 static eq_single_t
compute_bw_gain_db(eq_single_t gain
) {
601 eq_single_t bw_gain
= 0;
604 else if(gain
> -6 && gain
< 6)
612 eq_single_t
process(eq_single_t in
) {
615 //Process FO sections in serial connection
616 for(unsigned int i
= 0; i
< sections_
.size(); i
++) {
617 p1
= sections_
[i
].process(p0
);
625 class chebyshev_type2_bp_filter
: public bp_filter
{
627 std::vector
<fo_section
> sections_
;
629 chebyshev_type2_bp_filter(){}
631 chebyshev_type2_bp_filter(unsigned int N
,
632 eq_double_t w0
, eq_double_t wb
,
633 eq_double_t G
, eq_double_t Gb
, eq_double_t G0
) {
634 //Case if G == 0 : allpass
635 if(G
== 0 && G0
== 0) {
636 sections_
.push_back(fo_section());
640 //Get number of analog sections
641 unsigned int r
= N
%2;
642 unsigned int L
= (N
- r
)/2;
644 //Convert gains to linear scale
645 G
= conversions::db_2_lin(G
);
646 Gb
= conversions::db_2_lin(Gb
);
647 G0
= conversions::db_2_lin(G0
);
649 eq_double_t epsilon
= pow((eq_double_t
)((G
*G
- Gb
*Gb
)/
650 (Gb
*Gb
- G0
*G0
)),0.5);
651 eq_double_t g
= pow((eq_double_t
)(G
),1.0/N
);
652 eq_double_t eu
= pow(epsilon
+ sqrt(1 + epsilon
*epsilon
), 1.0/N
);
653 eq_double_t ew
= pow(G0
*epsilon
+ Gb
*sqrt(1 + epsilon
*epsilon
), 1.0/N
);
654 eq_double_t a
= (eu
- 1.0/eu
)/2.0;
655 eq_double_t b
= (ew
- g
*g
/ew
)/2.0;
656 eq_double_t tetta_b
= tan(wb
/2);
658 eq_double_t c0
= cos(w0
);
660 if (w0
== pi
/2) c0
=0;
661 if (w0
== pi
) c0
=- 1;
663 //Calculate every section
664 for(unsigned int i
= 1; i
<= L
; i
++) {
665 eq_double_t ui
= (2.0*i
-1.0)/N
;
666 eq_double_t ci
= cos(pi
*ui
/2.0);
667 eq_double_t si
= sin(pi
*ui
/2.0);
668 eq_double_t Di
= tetta_b
*tetta_b
+ 2*a
*si
*tetta_b
+ a
*a
+ ci
*ci
;
671 chebyshev_type2_fo_section(a
, ci
, tetta_b
, g
, si
, b
, Di
, c0
));
675 ~chebyshev_type2_bp_filter(){}
677 static eq_single_t
compute_bw_gain_db(eq_single_t gain
) {
678 eq_single_t bw_gain
= 0;
680 bw_gain
= -common_base_gain_db
;
681 else if(gain
> -6 && gain
< 6)
684 bw_gain
= common_base_gain_db
;
689 eq_single_t
process(eq_single_t in
) {
693 //Process FO sections in serial connection
694 for(unsigned int i
= 0; i
< sections_
.size(); i
++) {
695 p1
= sections_
[i
].process(p0
);
703 // ------------ eq1 ------------
704 // Equalizer with single precomputed filter for every band
708 eq_double_t sampling_frequency_
;
709 freq_grid freq_grid_
;
710 std::vector
<eq_single_t
> band_gains_
;
711 std::vector
<bp_filter
*> filters_
;
712 filter_type current_eq_type_
;
714 eq1():conv_(eq_min_max_gain_db
){}
715 eq1(const eq1
&):conv_(eq_min_max_gain_db
){}
717 void cleanup_filters_array() {
718 for(unsigned int j
= 0; j
< filters_
.size(); j
++)
723 eq1(const freq_grid
&fg
, filter_type eq_t
) : conv_(eq_min_max_gain_db
) {
724 sampling_frequency_
= default_sample_freq_hz
;
726 current_eq_type_
= eq_t
;
727 set_eq(freq_grid_
, eq_t
);
729 ~eq1(){cleanup_filters_array();}
731 eq_error_t
set_eq(freq_grid
& fg
, filter_type eqt
) {
733 cleanup_filters_array();
737 for(unsigned int i
= 0; i
< freq_grid_
.get_number_of_bands(); i
++) {
739 eq_double_t wb
= conversions::hz_2_rad(
740 freq_grid_
.get_freqs()[i
].max_freq
-
741 freq_grid_
.get_freqs()[i
].min_freq
,
742 sampling_frequency_
);
744 eq_double_t w0
= conversions::hz_2_rad(
745 freq_grid_
.get_freqs()[i
].center_freq
,
746 sampling_frequency_
);
749 case (butterworth
): {
750 butterworth_bp_filter
* bf
=
751 new butterworth_bp_filter(
752 default_eq_band_filters_order
,
756 butterworth_band_gain_db
,
760 filters_
.push_back(bf
);
765 chebyshev_type1_bp_filter
* cf1
=
766 new chebyshev_type1_bp_filter(
767 default_eq_band_filters_order
,
771 chebyshev1_band_base_gain_db
,
775 filters_
.push_back(cf1
);
780 chebyshev_type2_bp_filter
* cf2
=
781 new chebyshev_type2_bp_filter(
782 default_eq_band_filters_order
,
786 chebyshev2_band_base_gain_db
,
790 filters_
.push_back(cf2
);
795 current_eq_type_
= none
;
796 return invalid_input_data_error
;
799 band_gains_
.push_back(max_base_gain_db
);
802 current_eq_type_
= eqt
;
806 eq_error_t
set_eq(filter_type eqt
)
808 return set_eq(freq_grid_
, eqt
);
811 eq_error_t
set_sample_rate(eq_double_t sr
) {
812 eq_error_t err
= no_error
;
813 sampling_frequency_
= sr
;
814 err
= set_eq(freq_grid_
, current_eq_type_
);
819 eq_error_t
change_gains(std::vector
<eq_single_t
> band_gains
) {
820 if(band_gains_
.size() == band_gains
.size())
821 band_gains_
= band_gains
;
823 return invalid_input_data_error
;
828 eq_error_t
change_gains_db(std::vector
<eq_single_t
> band_gains
) {
829 if(band_gains_
.size() == band_gains
.size())
830 for(unsigned int j
= 0; j
< get_number_of_bands(); j
++)
831 band_gains_
[j
] = conv_
.fast_db_2_lin(band_gains
[j
]);
833 return invalid_input_data_error
;
838 eq_error_t
change_band_gain(unsigned int band_number
,
839 eq_single_t band_gain
) {
840 if(band_number
< get_number_of_bands())
841 band_gains_
[band_number
] = band_gain
;
843 return invalid_input_data_error
;
848 eq_error_t
change_band_gain_db(unsigned int band_number
,
849 eq_single_t band_gain
) {
850 if(band_number
< get_number_of_bands())
851 band_gains_
[band_number
] = conv_
.fast_db_2_lin(band_gain
);
853 return invalid_input_data_error
;
858 eq_error_t
sbs_process_band(unsigned int band_number
,
859 eq_single_t
*in
, eq_single_t
*out
) {
860 if(band_number
< get_number_of_bands())
861 *out
= band_gains_
[band_number
]*
862 filters_
[band_number
]->process(*in
);
864 return invalid_input_data_error
;
869 eq_error_t
sbs_process(eq_single_t
*in
, eq_single_t
*out
) {
870 eq_error_t err
= no_error
;
871 eq_single_t acc_out
= 0;
872 for(unsigned int j
= 0; j
< get_number_of_bands(); j
++) {
873 eq_single_t band_out
= 0;
874 err
= sbs_process_band(j
, in
, &band_out
);
882 filter_type
get_eq_type(){return current_eq_type_
;}
883 const char* get_string_eq_type(){return get_eq_text(current_eq_type_
);}
884 unsigned int get_number_of_bands() {
885 return freq_grid_
.get_number_of_bands();
887 const char* get_version(){return eq_version
;}
890 //!!! New functionality
892 // ------------ eq_channel ------------
893 // Precomputed equalizer channel,
894 // consists of vector of filters for every gain value
899 eq_single_t sampling_frequency_
;
900 eq_single_t min_max_gain_db_
;
901 eq_single_t gain_step_db_
;
903 unsigned int current_filter_index_
;
904 eq_single_t current_gain_db_
;
906 std::vector
<bp_filter
*> filters_
;
907 filter_type current_channel_type_
;
911 unsigned int get_flt_index(eq_single_t gain_db
) {
912 unsigned int number_of_filters
= filters_
.size();
913 eq_single_t scale_coef
= gain_db
/min_max_gain_db_
;
914 return (number_of_filters
/2) + (number_of_filters
/2)*scale_coef
;
917 void cleanup_filters_array() {
918 for(unsigned int j
= 0; j
< filters_
.size(); j
++)
923 eq_channel(filter_type ft
,
924 eq_single_t fs
, eq_single_t f0
, eq_single_t fb
,
925 eq_single_t min_max_gain_db
= p_eq_min_max_gain_db
,
926 eq_single_t step_db
= p_eq_gain_step_db
) {
929 sampling_frequency_
= fs
;
932 min_max_gain_db_
= min_max_gain_db
;
933 gain_step_db_
= step_db
;
935 current_gain_db_
= 0;
936 current_filter_index_
= 0;
938 current_channel_type_
= ft
;
940 set_channel(current_channel_type_
, sampling_frequency_
);
943 ~eq_channel(){cleanup_filters_array();}
945 eq_error_t
set_channel(filter_type ft
, eq_single_t fs
) {
947 eq_double_t wb
= conversions::hz_2_rad(fb_
, sampling_frequency_
);
948 eq_double_t w0
= conversions::hz_2_rad(f0_
, sampling_frequency_
);
950 for(eq_single_t gain
= -min_max_gain_db_
; gain
<= min_max_gain_db_
;
951 gain
+= gain_step_db_
) {
954 case (butterworth
): {
955 eq_single_t bw_gain
=
956 butterworth_bp_filter::compute_bw_gain_db(gain
);
958 butterworth_bp_filter
* bf
=
959 new butterworth_bp_filter(
960 default_eq_band_filters_order
,
968 filters_
.push_back(bf
);
972 eq_single_t bw_gain
=
973 chebyshev_type1_bp_filter::compute_bw_gain_db(gain
);
975 chebyshev_type1_bp_filter
* cf1
=
976 new chebyshev_type1_bp_filter(
977 default_eq_band_filters_order
,
985 filters_
.push_back(cf1
);
989 eq_single_t bw_gain
=
990 chebyshev_type2_bp_filter::compute_bw_gain_db(gain
);
992 chebyshev_type2_bp_filter
* cf2
=
993 new chebyshev_type2_bp_filter(
994 default_eq_band_filters_order
,
1002 filters_
.push_back(cf2
);
1006 current_channel_type_
= none
;
1007 return invalid_input_data_error
;
1012 //Get current filter index
1013 current_gain_db_
= 0;
1014 current_filter_index_
= get_flt_index(current_gain_db_
);
1019 eq_error_t
set_gain_db(eq_single_t db
) {
1020 if (db
> -min_max_gain_db_
&& db
< min_max_gain_db_
) {
1021 current_gain_db_
= db
;
1022 current_filter_index_
= get_flt_index(db
);
1025 return invalid_input_data_error
;
1030 eq_error_t
sbs_process(eq_single_t
*in
, eq_single_t
*out
) {
1031 *out
= filters_
[current_filter_index_
]->process(*in
);
1036 // ------------ eq2 ------------
1037 // Precomputed equalizer
1042 eq_double_t sampling_frequency_
;
1043 freq_grid freq_grid_
;
1044 std::vector
<eq_channel
*> channels_
;
1045 filter_type current_eq_type_
;
1047 void cleanup_channels_array() {
1048 for(unsigned int j
= 0; j
< channels_
.size(); j
++)
1049 delete channels_
[j
];
1053 eq2(freq_grid
&fg
, filter_type eq_t
) : conv_(eq_min_max_gain_db
) {
1054 sampling_frequency_
= default_sample_freq_hz
;
1056 current_eq_type_
= eq_t
;
1057 set_eq(freq_grid_
, eq_t
);
1059 ~eq2(){cleanup_channels_array();}
1061 eq_error_t
set_eq(const freq_grid
& fg
, filter_type ft
) {
1062 cleanup_channels_array();
1066 for(unsigned int i
= 0; i
< freq_grid_
.get_number_of_bands(); i
++) {
1067 band_freqs b_fres
= freq_grid_
.get_freqs()[i
];
1069 eq_channel
* eq_ch
= new eq_channel(ft
, sampling_frequency_
,
1070 b_fres
.center_freq
, b_fres
.max_freq
- b_fres
.min_freq
);
1072 channels_
.push_back(eq_ch
);
1073 channels_
[i
]->set_gain_db(p_eq_default_gain_db
);
1076 current_eq_type_
= ft
;
1080 eq_error_t
set_eq(filter_type ft
) {
1081 eq_error_t err
= set_eq(freq_grid_
, ft
);
1085 eq_error_t
set_sample_rate(eq_double_t sr
) {
1086 sampling_frequency_
= sr
;
1087 eq_error_t err
= set_eq(current_eq_type_
);
1091 eq_error_t
change_gains(std::vector
<eq_single_t
> band_gains
) {
1092 if(channels_
.size() == band_gains
.size())
1093 for(unsigned int j
= 0; j
< channels_
.size(); j
++)
1094 channels_
[j
]->set_gain_db(conv_
.fast_lin_2_db(band_gains
[j
]));
1096 return invalid_input_data_error
;
1101 eq_error_t
change_gains_db(std::vector
<eq_single_t
> band_gains
) {
1102 if(channels_
.size() == band_gains
.size())
1103 for(unsigned int j
= 0; j
< channels_
.size(); j
++)
1104 channels_
[j
]->set_gain_db(band_gains
[j
]);
1106 return invalid_input_data_error
;
1111 eq_error_t
change_band_gain(unsigned int band_number
,
1112 eq_single_t band_gain
) {
1113 if(band_number
< channels_
.size())
1114 channels_
[band_number
]->set_gain_db(conv_
.fast_lin_2_db(band_gain
));
1116 return invalid_input_data_error
;
1121 eq_error_t
change_band_gain_db(unsigned int band_number
,
1122 eq_single_t band_gain
) {
1123 if(band_number
< channels_
.size())
1124 channels_
[band_number
]->set_gain_db(band_gain
);
1126 return invalid_input_data_error
;
1131 eq_error_t
sbs_process_band(unsigned int band_number
,
1132 eq_single_t
*in
, eq_single_t
*out
) {
1133 if(band_number
< get_number_of_bands())
1134 channels_
[band_number
]->sbs_process(in
, out
);
1136 return invalid_input_data_error
;
1141 eq_error_t
sbs_process(eq_single_t
*in
, eq_single_t
*out
) {
1142 eq_error_t err
= no_error
;
1143 eq_single_t in_out
= *in
;
1144 for(unsigned int i
= 0; i
< get_number_of_bands(); i
++)
1145 err
= sbs_process_band(i
,&in_out
,&in_out
);
1152 filter_type
get_eq_type(){return current_eq_type_
;}
1153 const char* get_string_eq_type(){return get_eq_text(current_eq_type_
);}
1154 unsigned int get_number_of_bands() {
1155 return freq_grid_
.get_number_of_bands();
1157 const char* get_version(){return eq_version
;}
1160 } //namespace orfanidis_eq
1161 #endif //ORFANIDIS_EQ_H_