1 /*----------------------------------------------------------------------------
2 //
3 //                                3 Band EQ :)
4 //
5 // EQ.C - Main Source file for 3 band EQ
6 //
7 // (c) Neil C / Etanza Systems / 2K6
8 //
9 // Shouts / Loves / Moans = etanza at lycos dot co dot uk
10 //
11 // This work is hereby placed in the public domain for all purposes, including
12 // use in commercial applications.
13 //
14 // The author assumes NO RESPONSIBILITY for any problems caused by the use of
15 // this software.
16 //
17 //----------------------------------------------------------------------------*/
18 
19 /* NOTES :
20 //
21 // - Original filter code by Paul Kellet (musicdsp.pdf)
22 //
23 // - Uses 4 first order filters in series, should give 24dB per octave
24 //
25 // - Now with P4 Denormal fix :)
26 
27 
28 //----------------------------------------------------------------------------*/
29 
30 /* ----------
31 //| Includes |
32 // ----------*/
33 #include <stdio.h>
34 #include <string.h>
35 #include <math.h>
36 #include "eq.h"
37 #include "macros.h"
38 
39 
40 /* -----------
41 //| Constants |
42 // -----------*/
43 
44 static double vsa = (1.0 / 4294967295.0); /* Very small amount (Denormal Fix) */
45 
46 
47 /* ---------------
48 //| Initialise EQ |
49 // ---------------*/
50 
51 /* Recommended frequencies are ...
52 //
53 //  lowfreq  = 880  Hz
54 //  highfreq = 5000 Hz
55 //
56 // Set mixfreq to whatever rate your system is using (eg 48Khz)*/
57 
init_3band_state(EQSTATE * es,int lowfreq,int highfreq,int mixfreq)58 void init_3band_state(EQSTATE * es, int lowfreq, int highfreq, int mixfreq)
59 {
60     /* Clear state */
61 
62     memset(es, 0, sizeof(EQSTATE));
63 
64     /* Set Low/Mid/High gains to unity */
65 
66     es->lg = 1.0;
67     es->mg = 1.0;
68     es->hg = 1.0;
69 
70     /* Calculate filter cutoff frequencies */
71 
72     es->lf = 2 * sin(M_PI * ((double) lowfreq / (double) mixfreq));
73     es->hf = 2 * sin(M_PI * ((double) highfreq / (double) mixfreq));
74 }
75 
76 
77 /* ---------------
78 //| EQ one sample |
79 // ---------------*/
80 
81 /* - sample can be any range you like :)
82 //
83 // Note that the output will depend on the gain settings for each band
84 // (especially the bass) so may require clipping before output, but you
85 // knew that anyway :)*/
86 
do_3band(EQSTATE * es,int sample)87 double do_3band(EQSTATE * es, int sample)
88 {
89     /* Locals */
90 
91     double l, m, h;   /* Low / Mid / High - Sample Values */
92 
93     /* Filter #1 (lowpass) */
94 
95     es->f1p0 += (es->lf * ((double) sample - es->f1p0)) + vsa;
96     es->f1p1 += (es->lf * (es->f1p0 - es->f1p1));
97     es->f1p2 += (es->lf * (es->f1p1 - es->f1p2));
98     es->f1p3 += (es->lf * (es->f1p2 - es->f1p3));
99 
100     l = es->f1p3;
101 
102     /* Filter #2 (highpass) */
103 
104     es->f2p0 += (es->hf * ((double) sample - es->f2p0)) + vsa;
105     es->f2p1 += (es->hf * (es->f2p0 - es->f2p1));
106     es->f2p2 += (es->hf * (es->f2p1 - es->f2p2));
107     es->f2p3 += (es->hf * (es->f2p2 - es->f2p3));
108 
109     h = es->sdm3 - es->f2p3;
110 
111     /* Calculate midrange (signal - (low + high)) */
112 
113     /* m = es->sdm3 - (h + l); */
114     /* fix from http://www.musicdsp.org/showArchiveComment.php?ArchiveID=236 ? */
115     m = sample - (h + l);
116 
117     /* Scale, Combine and store */
118 
119     l *= es->lg;
120     m *= es->mg;
121     h *= es->hg;
122 
123     /* Shuffle history buffer */
124 
125     es->sdm3 = es->sdm2;
126     es->sdm2 = es->sdm1;
127     es->sdm1 = sample;
128 
129     /* Return result */
130 
131     return (int) (l + m + h);
132 }
133