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