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