1 /************************** BEGIN dsp-adapter.h **************************/
2 /************************************************************************
3  FAUST Architecture File
4  Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
5  ---------------------------------------------------------------------
6  This Architecture section is free software; you can redistribute it
7  and/or modify it under the terms of the GNU General Public License
8  as published by the Free Software Foundation; either version 3 of
9  the License, or (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; If not, see <http://www.gnu.org/licenses/>.
18 
19  EXCEPTION : As a special exception, you may create a larger work
20  that contains this FAUST architecture section and distribute
21  that work under terms of your choice, so long as this FAUST
22  architecture section is not modified.
23  ************************************************************************/
24 
25 #ifndef __dsp_adapter__
26 #define __dsp_adapter__
27 
28 #ifndef _WIN32
29 #  ifndef __FreeBSD__
30 #    include <alloca.h>
31 #  else
32 #    include <stdlib.h>
33 #  endif
34 #endif
35 #include <string.h>
36 #include <cmath>
37 #include <assert.h>
38 #include <stdio.h>
39 
40 #include "faust/dsp/dsp.h"
41 
42 // Adapts a DSP for a different number of inputs/outputs
43 class dsp_adapter : public decorator_dsp {
44 
45     private:
46 
47         FAUSTFLOAT** fAdaptedInputs;
48         FAUSTFLOAT** fAdaptedOutputs;
49         int fHWInputs;
50         int fHWOutputs;
51         int fBufferSize;
52 
adaptBuffers(FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)53         void adaptBuffers(FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
54         {
55             for (int i = 0; i < fHWInputs; i++) {
56                 fAdaptedInputs[i] = inputs[i];
57             }
58             for (int i = 0; i < fHWOutputs; i++) {
59                 fAdaptedOutputs[i] = outputs[i];
60             }
61         }
62 
63     public:
64 
dsp_adapter(dsp * dsp,int hw_inputs,int hw_outputs,int buffer_size)65         dsp_adapter(dsp* dsp, int hw_inputs, int hw_outputs, int buffer_size):decorator_dsp(dsp)
66         {
67             fHWInputs = hw_inputs;
68             fHWOutputs = hw_outputs;
69             fBufferSize = buffer_size;
70 
71             fAdaptedInputs = new FAUSTFLOAT*[dsp->getNumInputs()];
72             for (int i = 0; i < dsp->getNumInputs() - fHWInputs; i++) {
73                 fAdaptedInputs[i + fHWInputs] = new FAUSTFLOAT[buffer_size];
74                 memset(fAdaptedInputs[i + fHWInputs], 0, sizeof(FAUSTFLOAT) * buffer_size);
75             }
76 
77             fAdaptedOutputs = new FAUSTFLOAT*[dsp->getNumOutputs()];
78             for (int i = 0; i < dsp->getNumOutputs() - fHWOutputs; i++) {
79                 fAdaptedOutputs[i + fHWOutputs] = new FAUSTFLOAT[buffer_size];
80                 memset(fAdaptedOutputs[i + fHWOutputs], 0, sizeof(FAUSTFLOAT) * buffer_size);
81             }
82         }
83 
~dsp_adapter()84         virtual ~dsp_adapter()
85         {
86             for (int i = 0; i < fDSP->getNumInputs() - fHWInputs; i++) {
87                 delete [] fAdaptedInputs[i + fHWInputs];
88             }
89             delete [] fAdaptedInputs;
90 
91             for (int i = 0; i < fDSP->getNumOutputs() - fHWOutputs; i++) {
92                 delete [] fAdaptedOutputs[i + fHWOutputs];
93             }
94             delete [] fAdaptedOutputs;
95         }
96 
getNumInputs()97         virtual int getNumInputs() { return fHWInputs; }
getNumOutputs()98         virtual int getNumOutputs() { return fHWOutputs; }
99 
clone()100         virtual dsp_adapter* clone() { return new dsp_adapter(fDSP->clone(), fHWInputs, fHWOutputs, fBufferSize); }
101 
compute(double date_usec,int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)102         virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
103         {
104             adaptBuffers(inputs, outputs);
105             fDSP->compute(date_usec, count, fAdaptedInputs, fAdaptedOutputs);
106         }
107 
compute(int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)108         virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
109         {
110             adaptBuffers(inputs, outputs);
111             fDSP->compute(count, fAdaptedInputs, fAdaptedOutputs);
112         }
113 };
114 
115 // Adapts a DSP for a different sample size
116 template <typename REAL_INT, typename REAL_EXT>
117 class dsp_sample_adapter : public decorator_dsp {
118 
119     private:
120 
121         REAL_INT** fAdaptedInputs;
122         REAL_INT** fAdaptedOutputs;
123 
adaptInputBuffers(int count,FAUSTFLOAT ** inputs)124         void adaptInputBuffers(int count, FAUSTFLOAT** inputs)
125         {
126             for (int chan = 0; chan < fDSP->getNumInputs(); chan++) {
127                 for (int frame = 0; frame < count; frame++) {
128                     fAdaptedInputs[chan][frame] = REAL_INT(reinterpret_cast<REAL_EXT**>(inputs)[chan][frame]);
129                 }
130             }
131         }
132 
adaptOutputsBuffers(int count,FAUSTFLOAT ** outputs)133         void adaptOutputsBuffers(int count, FAUSTFLOAT** outputs)
134         {
135             for (int chan = 0; chan < fDSP->getNumOutputs(); chan++) {
136                 for (int frame = 0; frame < count; frame++) {
137                     reinterpret_cast<REAL_EXT**>(outputs)[chan][frame] = REAL_EXT(fAdaptedOutputs[chan][frame]);
138                 }
139             }
140         }
141 
142     public:
143 
dsp_sample_adapter(dsp * dsp)144         dsp_sample_adapter(dsp* dsp):decorator_dsp(dsp)
145         {
146             fAdaptedInputs = new REAL_INT*[dsp->getNumInputs()];
147             for (int i = 0; i < dsp->getNumInputs(); i++) {
148                 fAdaptedInputs[i] = new REAL_INT[4096];
149             }
150 
151             fAdaptedOutputs = new REAL_INT*[dsp->getNumOutputs()];
152             for (int i = 0; i < dsp->getNumOutputs(); i++) {
153                 fAdaptedOutputs[i] = new REAL_INT[4096];
154             }
155         }
156 
~dsp_sample_adapter()157         virtual ~dsp_sample_adapter()
158         {
159             for (int i = 0; i < fDSP->getNumInputs(); i++) {
160                 delete [] fAdaptedInputs[i];
161             }
162             delete [] fAdaptedInputs;
163 
164             for (int i = 0; i < fDSP->getNumOutputs(); i++) {
165                 delete [] fAdaptedOutputs[i];
166             }
167             delete [] fAdaptedOutputs;
168         }
169 
clone()170         virtual dsp_sample_adapter* clone() { return new dsp_sample_adapter(fDSP->clone()); }
171 
compute(int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)172         virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
173         {
174             assert(count <= 4096);
175             adaptInputBuffers(count, inputs);
176             // DSP base class uses FAUSTFLOAT** type, so reinterpret_cast has to be used even if the real DSP uses REAL_INT
177             fDSP->compute(count, reinterpret_cast<FAUSTFLOAT**>(fAdaptedInputs), reinterpret_cast<FAUSTFLOAT**>(fAdaptedOutputs));
178             adaptOutputsBuffers(count, outputs);
179         }
180 
compute(double date_usec,int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)181         virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
182         {
183             assert(count <= 4096);
184             adaptInputBuffers(count, inputs);
185             // DSP base class uses FAUSTFLOAT** type, so reinterpret_cast has to be used even if the real DSP uses REAL_INT
186             fDSP->compute(date_usec, count, reinterpret_cast<FAUSTFLOAT**>(fAdaptedInputs), reinterpret_cast<FAUSTFLOAT**>(fAdaptedOutputs));
187             adaptOutputsBuffers(count, outputs);
188         }
189 };
190 
191 // Template used to specialize double parameters expressed as NUM/DENOM
192 template <int NUM, int DENOM>
193 struct Double {
valueDouble194     static constexpr double value() { return double(NUM)/double(DENOM); }
195 };
196 
197 // Base class for filters
198 template <class fVslider0, int fVslider1>
199 struct Filter {
getFactorFilter200     inline int getFactor() { return fVslider1; }
201 };
202 
203 // Identity filter: copy input to output
204 template <class fVslider0, int fVslider1>
205 struct Identity : public Filter<fVslider0, fVslider1> {
getFactorIdentity206     inline int getFactor() { return fVslider1; }
207 
computeIdentity208     inline void compute(int count, FAUSTFLOAT* input0, FAUSTFLOAT* output0)
209     {
210         memcpy(output0, input0, count * sizeof(FAUSTFLOAT));
211     }
212 };
213 
214 // Generated with process = fi.lowpass(3, ma.SR*hslider("FCFactor", 0.4, 0.4, 0.5, 0.01)/hslider("Factor", 2, 2, 8, 1));
215 template <class fVslider0, int fVslider1, typename REAL>
216 struct LowPass3 : public Filter<fVslider0, fVslider1> {
217 
218     REAL fVec0[2];
219     REAL fRec1[2];
220     REAL fRec0[3];
221 
LowPass3_faustpower2_fLowPass3222     inline REAL LowPass3_faustpower2_f(REAL value)
223     {
224         return (value * value);
225     }
226 
LowPass3LowPass3227     LowPass3()
228     {
229         for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
230             fVec0[l0] = 0.0;
231         }
232         for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
233             fRec1[l1] = 0.0;
234         }
235         for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) {
236             fRec0[l2] = 0.0;
237         }
238     }
239 
computeLowPass3240     inline void compute(int count, FAUSTFLOAT* input0, FAUSTFLOAT* output0)
241     {
242         // Computed at template specialization time
243         REAL fSlow0 = std::tan((3.1415926535897931 * (REAL(fVslider0::value()) / REAL(fVslider1))));
244         REAL fSlow1 = (1.0 / fSlow0);
245         REAL fSlow2 = (1.0 / (((fSlow1 + 1.0000000000000002) / fSlow0) + 1.0));
246         REAL fSlow3 = (1.0 / (fSlow1 + 1.0));
247         REAL fSlow4 = (1.0 - fSlow1);
248         REAL fSlow5 = (((fSlow1 + -1.0000000000000002) / fSlow0) + 1.0);
249         REAL fSlow6 = (2.0 * (1.0 - (1.0 / LowPass3_faustpower2_f(fSlow0))));
250         // Computed at runtime
251         for (int i = 0; (i < count); i = (i + 1)) {
252             REAL fTemp0 = REAL(input0[i]);
253             fVec0[0] = fTemp0;
254             fRec1[0] = (0.0 - (fSlow3 * ((fSlow4 * fRec1[1]) - (fTemp0 + fVec0[1]))));
255             fRec0[0] = (fRec1[0] - (fSlow2 * ((fSlow5 * fRec0[2]) + (fSlow6 * fRec0[1]))));
256             output0[i] = FAUSTFLOAT((fSlow2 * (fRec0[2] + (fRec0[0] + (2.0 * fRec0[1])))));
257             fVec0[1] = fVec0[0];
258             fRec1[1] = fRec1[0];
259             fRec0[2] = fRec0[1];
260             fRec0[1] = fRec0[0];
261         }
262     }
263 };
264 
265 // Generated with process = fi.lowpass(4, ma.SR*hslider("FCFactor", 0.4, 0.4, 0.5, 0.01)/hslider("Factor", 2, 2, 8, 1));
266 template <class fVslider0, int fVslider1, typename REAL>
267 struct LowPass4 : public Filter<fVslider0, fVslider1> {
268 
269     REAL fRec1[3];
270     REAL fRec0[3];
271 
LowPass4_faustpower2_fLowPass4272     inline REAL LowPass4_faustpower2_f(REAL value)
273     {
274         return (value * value);
275     }
276 
LowPass4LowPass4277     LowPass4()
278     {
279         for (int l0 = 0; (l0 < 3); l0 = (l0 + 1)) {
280             fRec1[l0] = 0.0f;
281         }
282         for (int l1 = 0; (l1 < 3); l1 = (l1 + 1)) {
283             fRec0[l1] = 0.0f;
284         }
285     }
286 
computeLowPass4287     inline void compute(int count, FAUSTFLOAT* input0, FAUSTFLOAT* output0)
288     {
289         // Computed at template specialization time
290         REAL fSlow0 = std::tan((3.1415926535897931 * (REAL(fVslider0::value()) / REAL(fVslider1))));
291         REAL fSlow1 = (1.0 / fSlow0);
292         REAL fSlow2 = (1.0 / (((fSlow1 + 0.76536686473017945) / fSlow0) + 1.0));
293         REAL fSlow3 = (1.0 / (((fSlow1 + 1.8477590650225735) / fSlow0) + 1.0));
294         REAL fSlow4 = (((fSlow1 + -1.8477590650225735) / fSlow0) + 1.0);
295         REAL fSlow5 = (2.0 * (1.0 - (1.0 / LowPass4_faustpower2_f(fSlow0))));
296         REAL fSlow6 = (((fSlow1 + -0.76536686473017945) / fSlow0) + 1.0);
297         // Computed at runtime
298         for (int i = 0; (i < count); i = (i + 1)) {
299             fRec1[0] = (REAL(input0[i]) - (fSlow3 * ((fSlow4 * fRec1[2]) + (fSlow5 * fRec1[1]))));
300             fRec0[0] = ((fSlow3 * (fRec1[2] + (fRec1[0] + (2.0 * fRec1[1])))) - (fSlow2 * ((fSlow6 * fRec0[2]) + (fSlow5 * fRec0[1]))));
301             output0[i] = FAUSTFLOAT((fSlow2 * (fRec0[2] + (fRec0[0] + (2.0 * fRec0[1])))));
302             fRec1[2] = fRec1[1];
303             fRec1[1] = fRec1[0];
304             fRec0[2] = fRec0[1];
305             fRec0[1] = fRec0[0];
306         }
307     }
308 };
309 
310 // Generated with process = fi.lowpass3e(ma.SR*hslider("FCFactor", 0.4, 0.4, 0.5, 0.01)/hslider("Factor", 2, 2, 8, 1));
311 template <class fVslider0, int fVslider1, typename REAL>
312 struct LowPass3e : public Filter<fVslider0, fVslider1> {
313 
314     REAL fRec1[3];
315     REAL fVec0[2];
316     REAL fRec0[2];
317 
LowPass3e_faustpower2_fLowPass3e318     inline REAL LowPass3e_faustpower2_f(REAL value)
319     {
320         return (value * value);
321     }
322 
LowPass3eLowPass3e323     LowPass3e()
324     {
325         for (int l0 = 0; (l0 < 3); l0 = (l0 + 1)) {
326             fRec1[l0] = 0.0;
327         }
328         for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
329             fVec0[l1] = 0.0;
330         }
331         for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
332             fRec0[l2] = 0.0;
333         }
334     }
335 
computeLowPass3e336     inline void compute(int count, FAUSTFLOAT* input0, FAUSTFLOAT* output0)
337     {
338         // Computed at template specialization time
339         REAL fSlow0 = std::tan((3.1415926535897931 * (REAL(fVslider0::value()) / REAL(fVslider1))));
340         REAL fSlow1 = (1.0 / fSlow0);
341         REAL fSlow2 = (1.0 / (fSlow1 + 0.82244590899881598));
342         REAL fSlow3 = (0.82244590899881598 - fSlow1);
343         REAL fSlow4 = (1.0 / (((fSlow1 + 0.80263676416103003) / fSlow0) + 1.4122708937742039));
344         REAL fSlow5 = LowPass3e_faustpower2_f(fSlow0);
345         REAL fSlow6 = (0.019809144837788999 / fSlow5);
346         REAL fSlow7 = (fSlow6 + 1.1615164189826961);
347         REAL fSlow8 = (((fSlow1 + -0.80263676416103003) / fSlow0) + 1.4122708937742039);
348         REAL fSlow9 = (2.0 * (1.4122708937742039 - (1.0 / fSlow5)));
349         REAL fSlow10 = (2.0 * (1.1615164189826961 - fSlow6));
350         // Computed at runtime
351         for (int i = 0; (i < count); i = (i + 1)) {
352             fRec1[0] = (REAL(input0[i]) - (fSlow4 * ((fSlow8 * fRec1[2]) + (fSlow9 * fRec1[1]))));
353             REAL fTemp0 = (fSlow4 * (((fSlow7 * fRec1[0]) + (fSlow10 * fRec1[1])) + (fSlow7 * fRec1[2])));
354             fVec0[0] = fTemp0;
355             fRec0[0] = (0.0 - (fSlow2 * ((fSlow3 * fRec0[1]) - (fTemp0 + fVec0[1]))));
356             output0[i] = FAUSTFLOAT(fRec0[0]);
357             fRec1[2] = fRec1[1];
358             fRec1[1] = fRec1[0];
359             fVec0[1] = fVec0[0];
360             fRec0[1] = fRec0[0];
361         }
362     }
363 };
364 
365 // Generated with process = fi.lowpass6e(ma.SR*hslider("FCFactor", 0.4, 0.4, 0.5, 0.01)/hslider("Factor", 2, 2, 8, 1));
366 template <class fVslider0, int fVslider1, typename REAL>
367 struct LowPass6e : public Filter<fVslider0, fVslider1> {
368 
369     REAL fRec2[3];
370     REAL fRec1[3];
371     REAL fRec0[3];
372 
LowPass6e_faustpower2_fLowPass6e373     inline REAL LowPass6e_faustpower2_f(REAL value)
374     {
375         return (value * value);
376     }
377 
LowPass6eLowPass6e378     LowPass6e()
379     {
380         for (int l0 = 0; (l0 < 3); l0 = (l0 + 1)) {
381             fRec2[l0] = 0.0;
382         }
383         for (int l1 = 0; (l1 < 3); l1 = (l1 + 1)) {
384             fRec1[l1] = 0.0;
385         }
386         for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) {
387             fRec0[l2] = 0.0;
388         }
389     }
390 
computeLowPass6e391     inline void compute(int count, FAUSTFLOAT* input0, FAUSTFLOAT* output0)
392     {
393         // Computed at template specialization time
394         REAL fSlow0 = std::tan((3.1415926535897931 * (REAL(fVslider0::value()) / REAL(fVslider1))));
395         REAL fSlow1 = (1.0 / fSlow0);
396         REAL fSlow2 = (1.0 / (((fSlow1 + 0.16840487111358901) / fSlow0) + 1.0693584077073119));
397         REAL fSlow3 = LowPass6e_faustpower2_f(fSlow0);
398         REAL fSlow4 = (1.0 / fSlow3);
399         REAL fSlow5 = (fSlow4 + 53.536152954556727);
400         REAL fSlow6 = (1.0 / (((fSlow1 + 0.51247864188914105) / fSlow0) + 0.68962136448467504));
401         REAL fSlow7 = (fSlow4 + 7.6217312988706034);
402         REAL fSlow8 = (1.0 / (((fSlow1 + 0.78241304682164503) / fSlow0) + 0.24529150870616001));
403         REAL fSlow9 = (9.9999997054999994e-05 / fSlow3);
404         REAL fSlow10 = (fSlow9 + 0.00043322720055500002);
405         REAL fSlow11 = (((fSlow1 + -0.78241304682164503) / fSlow0) + 0.24529150870616001);
406         REAL fSlow12 = (2.0 * (0.24529150870616001 - fSlow4));
407         REAL fSlow13 = (2.0 * (0.00043322720055500002 - fSlow9));
408         REAL fSlow14 = (((fSlow1 + -0.51247864188914105) / fSlow0) + 0.68962136448467504);
409         REAL fSlow15 = (2.0 * (0.68962136448467504 - fSlow4));
410         REAL fSlow16 = (2.0 * (7.6217312988706034 - fSlow4));
411         REAL fSlow17 = (((fSlow1 + -0.16840487111358901) / fSlow0) + 1.0693584077073119);
412         REAL fSlow18 = (2.0 * (1.0693584077073119 - fSlow4));
413         REAL fSlow19 = (2.0 * (53.536152954556727 - fSlow4));
414         // Computed at runtime
415         for (int i = 0; (i < count); i = (i + 1)) {
416             fRec2[0] = (REAL(input0[i]) - (fSlow8 * ((fSlow11 * fRec2[2]) + (fSlow12 * fRec2[1]))));
417             fRec1[0] = ((fSlow8 * (((fSlow10 * fRec2[0]) + (fSlow13 * fRec2[1])) + (fSlow10 * fRec2[2]))) - (fSlow6 * ((fSlow14 * fRec1[2]) + (fSlow15 * fRec1[1]))));
418             fRec0[0] = ((fSlow6 * (((fSlow7 * fRec1[0]) + (fSlow16 * fRec1[1])) + (fSlow7 * fRec1[2]))) - (fSlow2 * ((fSlow17 * fRec0[2]) + (fSlow18 * fRec0[1]))));
419             output0[i] = FAUSTFLOAT((fSlow2 * (((fSlow5 * fRec0[0]) + (fSlow19 * fRec0[1])) + (fSlow5 * fRec0[2]))));
420             fRec2[2] = fRec2[1];
421             fRec2[1] = fRec2[0];
422             fRec1[2] = fRec1[1];
423             fRec1[1] = fRec1[0];
424             fRec0[2] = fRec0[1];
425             fRec0[1] = fRec0[0];
426         }
427     }
428 };
429 
430 // A "si.bus(N)" like hard-coded class
431 struct dsp_bus : public dsp {
432 
433     int fChannels;
434     int fSampleRate;
435 
dsp_busdsp_bus436     dsp_bus(int channels):fChannels(channels), fSampleRate(-1)
437     {}
438 
getNumInputsdsp_bus439     virtual int getNumInputs() { return fChannels; }
getNumOutputsdsp_bus440     virtual int getNumOutputs() { return fChannels; }
441 
getSampleRatedsp_bus442     virtual int getSampleRate() { return fSampleRate; }
443 
buildUserInterfacedsp_bus444     virtual void buildUserInterface(UI* ui_interface) {}
initdsp_bus445     virtual void init(int sample_rate)
446     {
447         //classInit(sample_rate);
448         instanceInit(sample_rate);
449     }
450 
instanceInitdsp_bus451     virtual void instanceInit(int sample_rate)
452     {
453         fSampleRate = sample_rate;
454         instanceConstants(sample_rate);
455         instanceResetUserInterface();
456         instanceClear();
457     }
458 
instanceConstantsdsp_bus459     virtual void instanceConstants(int sample_rate) {}
instanceResetUserInterfacedsp_bus460     virtual void instanceResetUserInterface() {}
instanceCleardsp_bus461     virtual void instanceClear() {}
462 
clonedsp_bus463     virtual dsp* clone() { return new dsp_bus(fChannels); }
464 
metadatadsp_bus465     virtual void metadata(Meta* m) {}
466 
computedsp_bus467     virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
468     {
469         for (int chan = 0; chan < fChannels; chan++) {
470             memcpy(outputs[chan], inputs[chan], sizeof(FAUSTFLOAT) * count);
471         }
472     }
473 
computedsp_bus474     virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
475     {
476         compute(count, inputs, outputs);
477     }
478 
479 };
480 
481 // Base class for sample-rate adapter
482 template <typename FILTER>
483 class sr_sampler : public decorator_dsp {
484 
485     protected:
486 
487         std::vector<FILTER> fInputLowPass;
488         std::vector<FILTER> fOutputLowPass;
489 
getFactor()490         inline int getFactor() { return this->fOutputLowPass[0].getFactor(); }
491 
492     public:
493 
sr_sampler(dsp * dsp)494         sr_sampler(dsp* dsp):decorator_dsp(dsp)
495         {
496             for (int chan = 0; chan < fDSP->getNumInputs(); chan++) {
497                 fInputLowPass.push_back(FILTER());
498             }
499             for (int chan = 0; chan < fDSP->getNumOutputs(); chan++) {
500                 fOutputLowPass.push_back(FILTER());
501             }
502         }
503 };
504 
505 // Down sample-rate adapter
506 template <typename FILTER>
507 class dsp_down_sampler : public sr_sampler<FILTER> {
508 
509     public:
510 
dsp_down_sampler(dsp * dsp)511         dsp_down_sampler(dsp* dsp):sr_sampler<FILTER>(dsp)
512         {}
513 
init(int sample_rate)514         virtual void init(int sample_rate)
515         {
516             this->fDSP->init(sample_rate / this->getFactor());
517         }
518 
instanceInit(int sample_rate)519         virtual void instanceInit(int sample_rate)
520         {
521             this->fDSP->instanceInit(sample_rate / this->getFactor());
522         }
523 
instanceConstants(int sample_rate)524         virtual void instanceConstants(int sample_rate)
525         {
526             this->fDSP->instanceConstants(sample_rate / this->getFactor());
527         }
528 
clone()529         virtual dsp_down_sampler* clone() { return new dsp_down_sampler(decorator_dsp::clone()); }
530 
compute(int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)531         virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
532         {
533             int real_count = count / this->getFactor();
534 
535             // Adapt inputs
536             FAUSTFLOAT** fInputs = (FAUSTFLOAT**)alloca(this->fDSP->getNumInputs() * sizeof(FAUSTFLOAT*));
537             for (int chan = 0; chan < this->fDSP->getNumInputs(); chan++) {
538                 // Lowpass filtering in place on 'inputs'
539                 this->fInputLowPass[chan].compute(count, inputs[chan], inputs[chan]);
540                 // Allocate fInputs with 'real_count' frames
541                 fInputs[chan] = (FAUSTFLOAT*)alloca(sizeof(FAUSTFLOAT) * real_count);
542                 // Decimate
543                 for (int frame = 0; frame < real_count; frame++) {
544                     fInputs[chan][frame] = inputs[chan][frame * this->getFactor()];
545                 }
546             }
547 
548             // Allocate fOutputs with 'real_count' frames
549             FAUSTFLOAT** fOutputs = (FAUSTFLOAT**)alloca(this->fDSP->getNumOutputs() * sizeof(FAUSTFLOAT*));
550             for (int chan = 0; chan < this->fDSP->getNumOutputs(); chan++) {
551                 fOutputs[chan] = (FAUSTFLOAT*)alloca(sizeof(FAUSTFLOAT) * real_count);
552             }
553 
554             // Compute at lower rate
555             this->fDSP->compute(real_count, fInputs, fOutputs);
556 
557             // Adapt outputs
558             for (int chan = 0; chan < this->fDSP->getNumOutputs(); chan++) {
559                 // Puts zeros
560                 memset(outputs[chan], 0, sizeof(FAUSTFLOAT) * count);
561                 for (int frame = 0; frame < real_count; frame++) {
562                     // Copy one sample every 'DownFactor'
563                     // Apply volume
564                     //outputs[chan][frame * this->getFactor()] = fOutputs[chan][frame] * this->getFactor();
565                     outputs[chan][frame * this->getFactor()] = fOutputs[chan][frame];
566                 }
567                 // Lowpass filtering in place on 'outputs'
568                 this->fOutputLowPass[chan].compute(count, outputs[chan], outputs[chan]);
569             }
570         }
571 
compute(double,int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)572         virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
573 };
574 
575 // Up sample-rate adapter
576 template <typename FILTER>
577 class dsp_up_sampler : public sr_sampler<FILTER> {
578 
579     public:
580 
dsp_up_sampler(dsp * dsp)581         dsp_up_sampler(dsp* dsp):sr_sampler<FILTER>(dsp)
582         {}
583 
init(int sample_rate)584         virtual void init(int sample_rate)
585         {
586             this->fDSP->init(sample_rate * this->getFactor());
587         }
588 
instanceInit(int sample_rate)589         virtual void instanceInit(int sample_rate)
590         {
591             this->fDSP->instanceInit(sample_rate * this->getFactor());
592         }
593 
instanceConstants(int sample_rate)594         virtual void instanceConstants(int sample_rate)
595         {
596             this->fDSP->instanceConstants(sample_rate * this->getFactor());
597         }
598 
clone()599         virtual dsp_up_sampler* clone() { return new dsp_up_sampler(decorator_dsp::clone()); }
600 
compute(int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)601         virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
602         {
603             int real_count = count * this->getFactor();
604 
605             // Adapt inputs
606             FAUSTFLOAT** fInputs = (FAUSTFLOAT**)alloca(this->fDSP->getNumInputs() * sizeof(FAUSTFLOAT*));
607 
608             for (int chan = 0; chan < this->fDSP->getNumInputs(); chan++) {
609                 // Allocate fInputs with 'real_count' frames
610                 fInputs[chan] = (FAUSTFLOAT*)alloca(sizeof(FAUSTFLOAT) * real_count);
611                 // Puts zeros
612                 memset(fInputs[chan], 0, sizeof(FAUSTFLOAT) * real_count);
613                 for (int frame = 0; frame < count; frame++) {
614                     // Copy one sample every 'UpFactor'
615                     fInputs[chan][frame * this->getFactor()] = inputs[chan][frame];
616                 }
617                 // Lowpass filtering in place on 'fInputs'
618                 this->fInputLowPass[chan].compute(real_count, fInputs[chan], fInputs[chan]);
619             }
620 
621             // Allocate fOutputs with 'real_count' frames
622             FAUSTFLOAT** fOutputs = (FAUSTFLOAT**)alloca(this->fDSP->getNumOutputs() * sizeof(FAUSTFLOAT*));
623 
624             for (int chan = 0; chan < this->fDSP->getNumOutputs(); chan++) {
625                 fOutputs[chan] = (FAUSTFLOAT*)alloca(sizeof(FAUSTFLOAT) * real_count);
626             }
627 
628             // Compute at upper rate
629             this->fDSP->compute(real_count, fInputs, fOutputs);
630 
631             // Adapt outputs
632             for (int chan = 0; chan < this->fDSP->getNumOutputs(); chan++) {
633                 // Lowpass filtering in place on 'fOutputs'
634                 this->fOutputLowPass[chan].compute(real_count, fOutputs[chan], fOutputs[chan]);
635                 // Decimate
636                 for (int frame = 0; frame < count; frame++) {
637                     // Apply volume
638                     //outputs[chan][frame] = fOutputs[chan][frame * this->getFactor()] * this->getFactor();
639                     outputs[chan][frame] = fOutputs[chan][frame * this->getFactor()];
640                 }
641             }
642         }
643 
compute(double,int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)644         virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
645 };
646 
647 // Create a UP/DS + Filter adapted DSP
648 template <typename REAL>
649 dsp* createSRAdapter(dsp* DSP, int ds = 0, int us = 0, int filter = 0)
650 {
651     if (ds > 0) {
652         switch (filter) {
653             case 0:
654                 if (ds == 2) {
655                     return new dsp_down_sampler<Identity<Double<1,1>, 2>>(DSP);
656                 } else if (ds == 3) {
657                     return new dsp_down_sampler<Identity<Double<1,1>, 3>>(DSP);
658                 } else if (ds == 4) {
659                     return new dsp_down_sampler<Identity<Double<1,1>, 4>>(DSP);
660                 } else if (ds == 8) {
661                     return new dsp_down_sampler<Identity<Double<1,1>, 8>>(DSP);
662                 } else if (ds == 16) {
663                     return new dsp_down_sampler<Identity<Double<1,1>, 16>>(DSP);
664                 } else if (ds == 32) {
665                     return new dsp_down_sampler<Identity<Double<1,1>, 32>>(DSP);
666                 } else {
667                     fprintf(stderr, "ERROR : ds factor type must be in [2..32] range\n");
668                     assert(false);
669                     return nullptr;
670                 }
671             case 1:
672                 if (ds == 2) {
673                     return new dsp_down_sampler<LowPass3<Double<45,100>, 2, REAL>>(DSP);
674                 } else if (ds == 3) {
675                     return new dsp_down_sampler<LowPass3<Double<45,100>, 3, REAL>>(DSP);
676                 } else if (ds == 4) {
677                     return new dsp_down_sampler<LowPass3<Double<45,100>, 4, REAL>>(DSP);
678                 } else if (ds == 8) {
679                     return new dsp_down_sampler<LowPass3<Double<45,100>, 8, REAL>>(DSP);
680                 } else if (ds == 16) {
681                     return new dsp_down_sampler<LowPass3<Double<45,100>, 16, REAL>>(DSP);
682                 } else if (ds == 32) {
683                     return new dsp_down_sampler<LowPass3<Double<45,100>, 32, REAL>>(DSP);
684                 } else {
685                     fprintf(stderr, "ERROR : ds factor type must be in [2..32] range\n");
686                     assert(false);
687                     return nullptr;
688                 }
689             case 2:
690                 if (ds == 2) {
691                     return new dsp_down_sampler<LowPass4<Double<45,100>, 2, REAL>>(DSP);
692                 } else if (ds == 3) {
693                     return new dsp_down_sampler<LowPass4<Double<45,100>, 3, REAL>>(DSP);
694                 } else if (ds == 4) {
695                     return new dsp_down_sampler<LowPass4<Double<45,100>, 4, REAL>>(DSP);
696                 } else if (ds == 8) {
697                     return new dsp_down_sampler<LowPass4<Double<45,100>, 8, REAL>>(DSP);
698                 } else if (ds == 16) {
699                     return new dsp_down_sampler<LowPass4<Double<45,100>, 16, REAL>>(DSP);
700                 } else if (ds == 32) {
701                     return new dsp_down_sampler<LowPass4<Double<45,100>, 32, REAL>>(DSP);
702                 } else {
703                     fprintf(stderr, "ERROR : ds factor type must be in [2..32] range\n");
704                     assert(false);
705                     return nullptr;
706                 }
707             case 3:
708                 if (ds == 2) {
709                     return new dsp_down_sampler<LowPass3e<Double<45,100>, 2, REAL>>(DSP);
710                 } else if (ds == 3) {
711                     return new dsp_down_sampler<LowPass3e<Double<45,100>, 3, REAL>>(DSP);
712                 } else if (ds == 4) {
713                     return new dsp_down_sampler<LowPass3e<Double<45,100>, 4, REAL>>(DSP);
714                 } else if (ds == 8) {
715                     return new dsp_down_sampler<LowPass3e<Double<45,100>, 8, REAL>>(DSP);
716                 } else if (ds == 16) {
717                     return new dsp_down_sampler<LowPass3e<Double<45,100>, 16, REAL>>(DSP);
718                 } else if (ds == 32) {
719                     return new dsp_down_sampler<LowPass3e<Double<45,100>, 32, REAL>>(DSP);
720                 } else {
721                     fprintf(stderr, "ERROR : ds factor type must be in [2..32] range\n");
722                     assert(false);
723                     return nullptr;
724                 }
725             case 4:
726                 if (ds == 2) {
727                     return new dsp_down_sampler<LowPass6e<Double<45,100>, 2, REAL>>(DSP);
728                 } else if (ds == 3) {
729                     return new dsp_down_sampler<LowPass6e<Double<45,100>, 3, REAL>>(DSP);
730                 } else if (ds == 4) {
731                     return new dsp_down_sampler<LowPass6e<Double<45,100>, 4, REAL>>(DSP);
732                 } else if (ds == 8) {
733                     return new dsp_down_sampler<LowPass6e<Double<45,100>, 8, REAL>>(DSP);
734                 } else if (ds == 16) {
735                     return new dsp_down_sampler<LowPass6e<Double<45,100>, 16, REAL>>(DSP);
736                 } else if (ds == 32) {
737                     return new dsp_down_sampler<LowPass6e<Double<45,100>, 32, REAL>>(DSP);
738                 } else {
739                     fprintf(stderr, "ERROR : ds factor type must be in [2..32] range\n");
740                     assert(false);
741                     return nullptr;
742                 }
743             default:
744                 fprintf(stderr, "ERROR : filter type must be in [0..4] range\n");
745                 assert(false);
746                 return nullptr;
747         }
748     } else if (us > 0) {
749 
750         switch (filter) {
751             case 0:
752                 if (us == 2) {
753                     return new dsp_up_sampler<Identity<Double<1,1>, 2>>(DSP);
754                 } else if (us == 3) {
755                     return new dsp_up_sampler<Identity<Double<1,1>, 3>>(DSP);
756                 } else if (us == 4) {
757                     return new dsp_up_sampler<Identity<Double<1,1>, 4>>(DSP);
758                 } else if (us == 8) {
759                     return new dsp_up_sampler<Identity<Double<1,1>, 8>>(DSP);
760                 } else if (us == 16) {
761                     return new dsp_up_sampler<Identity<Double<1,1>, 16>>(DSP);
762                 } else if (us == 32) {
763                     return new dsp_up_sampler<Identity<Double<1,1>, 32>>(DSP);
764                 } else {
765                     fprintf(stderr, "ERROR : us factor type must be in [2..32] range\n");
766                     assert(false);
767                     return nullptr;
768                 }
769             case 1:
770                 if (us == 2) {
771                     return new dsp_up_sampler<LowPass3<Double<45,100>, 2, REAL>>(DSP);
772                 } else if (us == 3) {
773                     return new dsp_up_sampler<LowPass3<Double<45,100>, 3, REAL>>(DSP);
774                 } else if (us == 4) {
775                     return new dsp_up_sampler<LowPass3<Double<45,100>, 4, REAL>>(DSP);
776                 } else if (us == 8) {
777                     return new dsp_up_sampler<LowPass3<Double<45,100>, 8, REAL>>(DSP);
778                 } else if (us == 16) {
779                     return new dsp_up_sampler<LowPass3<Double<45,100>, 16, REAL>>(DSP);
780                 } else if (us == 32) {
781                     return new dsp_up_sampler<LowPass3<Double<45,100>, 32, REAL>>(DSP);
782                 } else {
783                     fprintf(stderr, "ERROR : us factor type must be in [2..32] range\n");
784                     assert(false);
785                     return nullptr;
786                 }
787             case 2:
788                 if (us == 2) {
789                     return new dsp_up_sampler<LowPass4<Double<45,100>, 2, REAL>>(DSP);
790                 } else if (us == 3) {
791                     return new dsp_up_sampler<LowPass4<Double<45,100>, 3, REAL>>(DSP);
792                 } else if (us == 4) {
793                     return new dsp_up_sampler<LowPass4<Double<45,100>, 4, REAL>>(DSP);
794                 } else if (us == 8) {
795                     return new dsp_up_sampler<LowPass4<Double<45,100>, 8, REAL>>(DSP);
796                 } else if (us == 16) {
797                     return new dsp_up_sampler<LowPass4<Double<45,100>, 16, REAL>>(DSP);
798                 } else if (us == 32) {
799                     return new dsp_up_sampler<LowPass4<Double<45,100>, 32, REAL>>(DSP);
800                 } else {
801                     fprintf(stderr, "ERROR : us factor type must be in [2..32] range\n");
802                     assert(false);
803                     return nullptr;
804                 }
805             case 3:
806                 if (us == 2) {
807                     return new dsp_up_sampler<LowPass3e<Double<45,100>, 2, REAL>>(DSP);
808                 } else if (us == 3) {
809                     return new dsp_up_sampler<LowPass3e<Double<45,100>, 3, REAL>>(DSP);
810                 } else if (us == 4) {
811                     return new dsp_up_sampler<LowPass3e<Double<45,100>, 4, REAL>>(DSP);
812                 } else if (us == 8) {
813                     return new dsp_up_sampler<LowPass3e<Double<45,100>, 8, REAL>>(DSP);
814                 } else if (us == 16) {
815                     return new dsp_up_sampler<LowPass3e<Double<45,100>, 16, REAL>>(DSP);
816                 } else if (us == 32) {
817                     return new dsp_up_sampler<LowPass3e<Double<45,100>, 32, REAL>>(DSP);
818                 } else {
819                     fprintf(stderr, "ERROR : us factor type must be in [2..32] range\n");
820                     assert(false);
821                     return nullptr;
822                 }
823             case 4:
824                 if (us == 2) {
825                     return new dsp_up_sampler<LowPass6e<Double<45,100>, 2, REAL>>(DSP);
826                 } else if (us == 3) {
827                     return new dsp_up_sampler<LowPass6e<Double<45,100>, 3, REAL>>(DSP);
828                 } else if (us == 4) {
829                     return new dsp_up_sampler<LowPass6e<Double<45,100>, 4, REAL>>(DSP);
830                 } else if (us == 8) {
831                     return new dsp_up_sampler<LowPass6e<Double<45,100>, 8, REAL>>(DSP);
832                 } else if (us == 16) {
833                     return new dsp_up_sampler<LowPass6e<Double<45,100>, 16, REAL>>(DSP);
834                 } else if (us == 32) {
835                     return new dsp_up_sampler<LowPass6e<Double<45,100>, 32, REAL>>(DSP);
836                 } else {
837                     fprintf(stderr, "ERROR : us factor type must be in [2..32] range\n");
838                     assert(false);
839                     return nullptr;
840                 }
841             default:
842                 fprintf(stderr, "ERROR : filter type must be in [0..4] range\n");
843                 assert(false);
844                 return nullptr;
845         }
846     } else {
847         return DSP;
848     }
849 }
850 
851 #endif
852 /************************** END dsp-adapter.h **************************/
853