1 /*
2 
3   CompBand.C - 4 Bands Compressor
4 
5   Using Compressor and AnalogFilters by other authors.
6 
7   Based on artscompressor.cc by Matthias Kretz <kretz@kde.org>
8   Stefan Westerfeld <stefan@space.twc.de>
9 
10   Modified by Ryan Billing & Josep Andreu
11 
12   ZynAddSubFX - a software synthesizer
13   Copyright (C) 2002-2005 Nasca Octavian Paul
14   Author: Nasca Octavian Paul
15 
16   This program is free software; you can redistribute it and/or modify
17   it under the terms of version 2 of the GNU General Public License
18   as published by the Free Software Foundation.
19 
20   This program is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   GNU General Public License (version 2) for more details.
24 
25   You should have received a copy of the GNU General Public License (version 2)
26   along with this program; if not, write to the Free Software Foundation,
27   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
28 */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <math.h>
33 #include "CompBand.h"
34 
35 /*
36  * Waveshape (this is called by OscilGen::waveshape and Distorsion::process)
37  */
38 
39 
40 
CompBand(float * efxoutl_,float * efxoutr_,double sample_rate,uint32_t intermediate_bufsize)41 CompBand::CompBand (float * efxoutl_, float * efxoutr_, double sample_rate, uint32_t intermediate_bufsize)
42 {
43     efxoutl = efxoutl_;
44     efxoutr = efxoutr_;
45 
46     lowl = (float *) malloc (sizeof (float) * intermediate_bufsize);
47     lowr = (float *) malloc (sizeof (float) * intermediate_bufsize);
48     midll = (float *) malloc (sizeof (float) * intermediate_bufsize);
49     midlr = (float *) malloc (sizeof (float) * intermediate_bufsize);
50     midhl = (float *) malloc (sizeof (float) * intermediate_bufsize);
51     midhr = (float *) malloc (sizeof (float) * intermediate_bufsize);
52     highl = (float *) malloc (sizeof (float) * intermediate_bufsize);
53     highr = (float *) malloc (sizeof (float) * intermediate_bufsize);
54 
55 
56     interpbuf = new float[intermediate_bufsize];
57     lpf1l = new AnalogFilter (2, 500.0f,.7071f, 0, sample_rate, interpbuf);
58     lpf1r = new AnalogFilter (2, 500.0f,.7071f, 0, sample_rate, interpbuf);
59     hpf1l = new AnalogFilter (3, 500.0f,.7071f, 0, sample_rate, interpbuf);
60     hpf1r = new AnalogFilter (3, 500.0f,.7071f, 0, sample_rate, interpbuf);
61     lpf2l = new AnalogFilter (2, 2500.0f,.7071f, 0, sample_rate, interpbuf);
62     lpf2r = new AnalogFilter (2, 2500.0f,.7071f, 0, sample_rate, interpbuf);
63     hpf2l = new AnalogFilter (3, 2500.0f,.7071f, 0, sample_rate, interpbuf);
64     hpf2r = new AnalogFilter (3, 2500.0f,.7071f, 0, sample_rate, interpbuf);
65     lpf3l = new AnalogFilter (2, 5000.0f,.7071f, 0, sample_rate, interpbuf);
66     lpf3r = new AnalogFilter (2, 5000.0f,.7071f, 0, sample_rate, interpbuf);
67     hpf3l = new AnalogFilter (3, 5000.0f,.7071f, 0, sample_rate, interpbuf);
68     hpf3r = new AnalogFilter (3, 5000.0f,.7071f, 0, sample_rate, interpbuf);
69 
70 
71     CL = new Compressor(efxoutl,efxoutr, sample_rate);
72     CML = new Compressor(efxoutl,efxoutr, sample_rate);
73     CMH = new Compressor(efxoutl,efxoutr, sample_rate);
74     CH = new Compressor(efxoutl,efxoutr, sample_rate);
75 
76     CL->Compressor_Change_Preset(0,5);
77     CML->Compressor_Change_Preset(0,5);
78     CMH->Compressor_Change_Preset(0,5);
79     CH->Compressor_Change_Preset(0,5);
80 
81 
82     //default values
83     Ppreset = 0;
84     Pvolume = 50;
85 
86     setpreset (Ppreset);
87     cleanup ();
88 };
89 
~CompBand()90 CompBand::~CompBand ()
91 {
92 	free(lowl);
93 	free(lowr);
94 	free(midll);
95 	free(midlr);
96 	free(midhl);
97 	free(midhr);
98 	free(highl);
99 	free(highr);
100 
101     delete lpf1l;
102     delete lpf1r;
103     delete hpf1l;
104     delete hpf1r;
105     delete lpf2l;
106     delete lpf2r;
107     delete hpf2l;
108     delete hpf2r;
109     delete lpf3l;
110     delete lpf3r;
111     delete hpf3l;
112     delete hpf3r;
113     delete[] interpbuf;
114 
115     delete CL;
116     delete CML;
117     delete CMH;
118     delete CH;
119 };
120 
121 /*
122  * Cleanup the effect
123  */
124 void
cleanup()125 CompBand::cleanup ()
126 {
127     lpf1l->cleanup ();
128     hpf1l->cleanup ();
129     lpf1r->cleanup ();
130     hpf1r->cleanup ();
131     lpf2l->cleanup ();
132     hpf2l->cleanup ();
133     lpf2r->cleanup ();
134     hpf2r->cleanup ();
135     lpf3l->cleanup ();
136     hpf3l->cleanup ();
137     lpf3r->cleanup ();
138     hpf3r->cleanup ();
139     CL->cleanup();
140     CML->cleanup();
141     CMH->cleanup();
142     CH->cleanup();
143 
144 };
145 /*
146  * Effect output
147  */
148 void
out(float * smpsl,float * smpsr,uint32_t period)149 CompBand::out (float * smpsl, float * smpsr, uint32_t period)
150 {
151     unsigned int i;
152 
153 
154     memcpy(lowl,smpsl,sizeof(float) * period);
155     memcpy(midll,smpsl,sizeof(float) * period);
156     memcpy(midhl,smpsl,sizeof(float) * period);
157     memcpy(highl,smpsl,sizeof(float) * period);
158 
159     lpf1l->filterout(lowl, period);
160     hpf1l->filterout(midll, period);
161     lpf2l->filterout(midll, period);
162     hpf2l->filterout(midhl, period);
163     lpf3l->filterout(midhl, period);
164     hpf3l->filterout(highl, period);
165 
166     memcpy(lowr,smpsr,sizeof(float) * period);
167     memcpy(midlr,smpsr,sizeof(float) * period);
168     memcpy(midhr,smpsr,sizeof(float) * period);
169     memcpy(highr,smpsr,sizeof(float) * period);
170 
171     lpf1r->filterout(lowr, period);
172     hpf1r->filterout(midlr, period);
173     lpf2r->filterout(midlr, period);
174     hpf2r->filterout(midhr, period);
175     lpf3r->filterout(midhr, period);
176     hpf3r->filterout(highr, period);
177 
178 
179     CL->out(lowl,lowr, period);
180     CML->out(midll,midlr, period);
181     CMH->out(midhl,midhr, period);
182     CH->out(highl,highr, period);
183 
184 
185     for (i = 0; i < period; i++) {
186         efxoutl[i]=(lowl[i]+midll[i]+midhl[i]+highl[i])*level;
187         efxoutr[i]=(lowr[i]+midlr[i]+midhr[i]+highr[i])*level;
188     }
189 
190 
191 
192 };
193 
194 
195 /*
196  * Parameter control
197  */
198 void
setvolume(int value)199 CompBand::setvolume (int value)
200 {
201     Pvolume = value;
202     outvolume = (float)Pvolume / 128.0f;
203 
204 };
205 
206 
207 void
setlevel(int value)208 CompBand::setlevel (int value)
209 {
210     Plevel = value;
211     level = dB2rap (60.0f * (float)value / 127.0f - 36.0f);
212 
213 
214 };
215 
216 
217 
218 void
setratio(int ch,int value)219 CompBand::setratio(int ch, int value)
220 {
221 
222     switch(ch) {
223     case 0:
224         CL->Compressor_Change(2,value);
225         break;
226     case 1:
227         CML->Compressor_Change(2,value);
228         break;
229     case 2:
230         CMH->Compressor_Change(2,value);
231         break;
232     case 3:
233         CH->Compressor_Change(2,value);
234         break;
235     }
236 }
237 
238 
239 void
setthres(int ch,int value)240 CompBand::setthres(int ch, int value)
241 {
242 
243     switch(ch) {
244     case 0:
245         CL->Compressor_Change(1,value);
246         break;
247     case 1:
248         CML->Compressor_Change(1,value);
249         break;
250     case 2:
251         CMH->Compressor_Change(1,value);
252         break;
253     case 3:
254         CH->Compressor_Change(1,value);
255         break;
256     }
257 }
258 
259 
260 
261 
262 void
setCross1(int value)263 CompBand::setCross1 (int value)
264 {
265     Cross1 = value;
266     lpf1l->setfreq ((float)value);
267     lpf1r->setfreq ((float)value);
268     hpf1l->setfreq ((float)value);
269     hpf1r->setfreq ((float)value);
270 
271 };
272 
273 void
setCross2(int value)274 CompBand::setCross2 (int value)
275 {
276     Cross2 = value;
277     hpf2l->setfreq ((float)value);
278     hpf2r->setfreq ((float)value);
279     lpf2l->setfreq ((float)value);
280     lpf2r->setfreq ((float)value);
281 
282 };
283 
284 void
setCross3(int value)285 CompBand::setCross3 (int value)
286 {
287     Cross3 = value;
288     hpf3l->setfreq ((float)value);
289     hpf3r->setfreq ((float)value);
290     lpf3l->setfreq ((float)value);
291     lpf3r->setfreq ((float)value);
292 
293 };
294 
295 
296 void
setpreset(int npreset)297 CompBand::setpreset (int npreset)
298 {
299     const int PRESET_SIZE = 13;
300     const int NUM_PRESETS = 3;
301     int pdata[PRESET_SIZE];
302     int presets[NUM_PRESETS][PRESET_SIZE] = {
303         //Good Start
304         {0, 16, 16, 16, 16, 0, 0, 0, 0, 1000, 5000, 10000, 48},
305 
306         //Loudness
307         {0, 16, 2, 2, 4, -16, 24, 24, -8, 140, 1000, 5000, 48},
308 
309         //Loudness 2
310         {64, 16, 2, 2, 2, -32, 24, 24, 24, 100, 1000, 5000, 48}
311 
312     };
313 
314     if(npreset>NUM_PRESETS-1) {
315         Fpre->ReadPreset(43,npreset-NUM_PRESETS+1,pdata);
316         for (int n = 0; n < PRESET_SIZE; n++)
317             changepar (n, pdata[n]);
318     } else {
319         for (int n = 0; n < PRESET_SIZE; n++)
320             changepar (n, presets[npreset][n]);
321     }
322     Ppreset = npreset;
323     cleanup ();
324 };
325 
326 
327 void
changepar(int npar,int value)328 CompBand::changepar (int npar, int value)
329 {
330     switch (npar) {
331     case 0:
332         setvolume (value);
333         break;
334     case 1:
335         PLratio = value;
336         setratio(0,value);
337         break;
338     case 2:
339         PMLratio = value;
340         setratio(1,value);
341         break;
342     case 3:
343         PMHratio = value;
344         setratio(2,value);
345         break;
346     case 4:
347         PHratio = value;
348         setratio(3,value);
349         break;
350     case 5:
351         PLthres = value;
352         setthres(0,value);
353         break;
354     case 6:
355         PMLthres = value;
356         setthres(1,value);
357         break;
358     case 7:
359         PMHthres = value;
360         setthres(2,value);
361         break;
362     case 8:
363         PHthres = value;
364         setthres(3,value);
365         break;
366     case 9:
367         setCross1 (value);
368         break;
369     case 10:
370         setCross2 (value);
371         break;
372     case 11:
373         setCross3(value);
374         break;
375     case 12:
376         setlevel(value);
377         break;
378 
379 
380     };
381 };
382 
383 int
getpar(int npar)384 CompBand::getpar (int npar)
385 {
386     switch (npar) {
387     case 0:
388         return (Pvolume);
389         break;
390     case 1:
391         return (PLratio);
392         break;
393     case 2:
394         return (PMLratio);
395         break;
396     case 3:
397         return (PMHratio);
398         break;
399     case 4:
400         return (PHratio);
401         break;
402     case 5:
403         return (PLthres);
404         break;
405     case 6:
406         return (PMLthres);
407         break;
408     case 7:
409         return (PMHthres);
410         break;
411     case 8:
412         return (PHthres);
413         break;
414     case 9:
415         return (Cross1);
416         break;
417     case 10:
418         return (Cross2);
419         break;
420     case 11:
421         return (Cross3);
422         break;
423     case 12:
424         return (Plevel);
425         break;
426     };
427     return (0);			//in case of bogus parameter number
428 };
429 
430