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