1 /************************** BEGIN dsp-tools.h **************************/
2 /************************************************************************
3  FAUST Architecture File
4  Copyright (C) 2003-2017 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_tools__
26 #define __dsp_tools__
27 
28 #include <assert.h>
29 #include <string.h>
30 
31 #ifndef FAUSTFLOAT
32 #define FAUSTFLOAT float
33 #endif
34 
35 class Deinterleaver
36 {
37 
38     private:
39 
40         int fNumFrames;
41         int fNumInputs;
42         int fNumOutputs;
43 
44         FAUSTFLOAT* fInput;
45         FAUSTFLOAT* fOutputs[256];
46 
47     public:
48 
Deinterleaver(int numFrames,int numInputs,int numOutputs)49         Deinterleaver(int numFrames, int numInputs, int numOutputs)
50         {
51             fNumFrames = numFrames;
52             fNumInputs = numInputs;
53             fNumOutputs = std::max<int>(numInputs, numOutputs);
54 
55             // allocate interleaved input channel
56             fInput = new FAUSTFLOAT[fNumFrames * fNumInputs];
57 
58             // allocate separate output channels
59             for (int i = 0; i < fNumOutputs; i++) {
60                 fOutputs[i] = new FAUSTFLOAT[fNumFrames];
61             }
62         }
63 
~Deinterleaver()64         ~Deinterleaver()
65         {
66             // free interleaved input channel
67             delete [] fInput;
68 
69             // free separate output channels
70             for (int i = 0; i < fNumOutputs; i++) {
71                 delete [] fOutputs[i];
72             }
73         }
74 
input()75         FAUSTFLOAT* input() { return fInput; }
76 
outputs()77         FAUSTFLOAT** outputs() { return fOutputs; }
78 
deinterleave()79         void deinterleave()
80         {
81             for (int s = 0; s < fNumFrames; s++) {
82                 for (int c = 0; c < fNumInputs; c++) {
83                     fOutputs[c][s] = fInput[c + s * fNumInputs];
84                 }
85             }
86         }
87 };
88 
89 class Interleaver
90 {
91 
92     private:
93 
94         int fNumFrames;
95         int fNumInputs;
96         int fNumOutputs;
97 
98         FAUSTFLOAT* fInputs[256];
99         FAUSTFLOAT* fOutput;
100 
101     public:
102 
Interleaver(int numFrames,int numInputs,int numOutputs)103         Interleaver(int numFrames, int numInputs, int numOutputs)
104         {
105             fNumFrames = numFrames;
106             fNumInputs 	= std::max(numInputs, numOutputs);
107             fNumOutputs = numOutputs;
108 
109             // allocate separate input channels
110             for (int i = 0; i < fNumInputs; i++) {
111                 fInputs[i] = new FAUSTFLOAT[fNumFrames];
112             }
113 
114             // allocate interleaved output channel
115             fOutput = new FAUSTFLOAT[fNumFrames * fNumOutputs];
116         }
117 
~Interleaver()118         ~Interleaver()
119         {
120             // free separate input channels
121             for (int i = 0; i < fNumInputs; i++) {
122                 delete [] fInputs[i];
123             }
124 
125             // free interleaved output channel
126             delete [] fOutput;
127         }
128 
inputs()129         FAUSTFLOAT** inputs() { return fInputs; }
130 
output()131         FAUSTFLOAT* output() { return fOutput; }
132 
interleave()133         void interleave()
134         {
135             for (int s = 0; s < fNumFrames; s++) {
136                 for (int c = 0; c < fNumOutputs; c++) {
137                     fOutput[c + s * fNumOutputs] = fInputs[c][s];
138                 }
139             }
140         }
141 };
142 
143 //=============================================================================
144 // An AudioChannels is a group of non-interleaved buffers that knows how to read
145 // from or write to an interleaved buffer. The interleaved buffer may have a
146 // different number of channels than the AudioChannels internal channels.
147 //=============================================================================
148 
149 class AudioChannels
150 {
151 
152     protected:
153 
154         const unsigned int fNumFrames;
155         const unsigned int fNumChannels;
156         FAUSTFLOAT** fChannels;
157 
158     public:
159 
AudioChannels(int nframes,int nchannels)160         AudioChannels(int nframes, int nchannels) : fNumFrames(nframes), fNumChannels(nchannels)
161         {
162             fChannels = new FAUSTFLOAT*[nchannels];
163 
164             // allocate audio channels
165             for (unsigned int i = 0; i < fNumChannels; i++) {
166                 fChannels[i] = new FAUSTFLOAT[fNumFrames];
167                 memset(fChannels[i], 0, sizeof(FAUSTFLOAT) * fNumFrames);
168             }
169         }
170 
~AudioChannels()171         virtual ~AudioChannels()
172         {
173             // free separate input channels
174             for (int i = 0; i < fNumChannels; i++) {
175                 delete[] fChannels[i];
176             }
177             delete[] fChannels;
178         }
179 
180         //---------------------------------------------------------------------------------------
181         // interleavedRead: read, from the interleaved buffer <inbuffer>, <length> frames on
182         // <inchannels> channels. The samples are written to the <fNumChannels> internal
183         // <fChannels>.
interleavedRead(float * inbuffer,unsigned int length,unsigned int inchannels)184         void interleavedRead(float* inbuffer, unsigned int length, unsigned int inchannels)
185         {
186             assert(length <= fNumFrames);
187             unsigned int C = std::min<unsigned int>(inchannels, fNumChannels);
188             unsigned int F = std::min<unsigned int>(length, fNumFrames);
189 
190             for (unsigned int f = 0; f < F; f++) {
191                 unsigned int p = f * inchannels;
192                 for (unsigned int c = 0; c < C; c++) {
193                     fChannels[c][f] = inbuffer[p++];
194                 }
195                 for (unsigned int c = C; c < fNumChannels; c++) {
196                     fChannels[c][f] = 0;
197                 }
198             }
199         }
200 
201         //----------------------------------------------------------------------------------------
202         // interleavedWrite: write to the interleaved buffer <inbuffer>, <length> frames on
203         // <outchannels> channels. The samples are read from <fNumChannels> internal
204         // <fChannels>.
interleavedWrite(float * outbuffer,unsigned int length,unsigned int outchannels)205         void interleavedWrite(float* outbuffer, unsigned int length, unsigned int outchannels)
206         {
207             assert(length <= fNumFrames);
208             unsigned int C = std::min<unsigned int>(outchannels, fNumChannels);
209             unsigned int F = std::min<unsigned int>(length, fNumFrames);
210 
211             for (unsigned int f = 0; f < F; f++) {
212                 unsigned int p = f * outchannels;
213                 for (unsigned int c = 0; c < C; c++) {
214                     outbuffer[p++] = fChannels[c][f];
215                 }
216                 for (unsigned int c = C; c < outchannels; c++) {
217                     outbuffer[p++] = 0;
218                 }
219             }
220         }
221 
222         //----------------------------------------------------------------------------------------
223         // buffers: the internal buffers ready to use in the compute() method of a Faust dsp
224 
buffers()225         FAUSTFLOAT** buffers() { return fChannels; }
226 };
227 
228 #endif
229 /************************** END dsp-tools.h **************************/
230