1 /************************** BEGIN dummy-audio.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 __dummy_audio__ 26 #define __dummy_audio__ 27 28 #include <stdlib.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <limits.h> 32 #include <iostream> 33 #include <iomanip> 34 35 #ifdef USE_PTHREAD 36 #include <pthread.h> 37 #else 38 #include <thread> 39 #endif 40 41 #include "faust/dsp/dsp.h" 42 #include "faust/audio/audio.h" 43 44 #define BUFFER_TO_RENDER 10 45 46 struct dummyaudio_base : public audio { 47 48 virtual void render() = 0; 49 }; 50 51 template <typename REAL> 52 class dummyaudio_real : public dummyaudio_base { 53 54 private: 55 56 dsp* fDSP; 57 58 int fSampleRate; 59 int fBufferSize; 60 61 REAL** fInChannel; 62 REAL** fOutChannel; 63 64 int fNumInputs; 65 int fNumOutputs; 66 67 bool fRunning; 68 69 int fRender; 70 int fCount; 71 int fSample; 72 bool fManager; 73 bool fExit; 74 runAux()75 void runAux() 76 { 77 try { 78 process(); 79 } catch (...) { 80 if (fExit) exit(EXIT_FAILURE); 81 } 82 } 83 84 #ifdef USE_PTHREAD 85 pthread_t fAudioThread; run(void * ptr)86 static void* run(void* ptr) 87 { 88 static_cast<dummyaudio_real*>(ptr)->runAux(); 89 } 90 #else 91 std::thread* fAudioThread = nullptr; run(dummyaudio_real * audio)92 static void run(dummyaudio_real* audio) 93 { 94 audio->runAux(); 95 } 96 #endif 97 process()98 void process() 99 { 100 while (fRunning && (fRender-- > 0)) { 101 if (fSample > 0) { std::cout << "Render one buffer\n"; } 102 render(); 103 } 104 fRunning = false; 105 } 106 107 public: 108 109 dummyaudio_real(int sr, int bs, 110 int count = BUFFER_TO_RENDER, 111 int sample = -1, 112 bool manager = false, 113 bool exit = false) fSampleRate(sr)114 :fSampleRate(sr), fBufferSize(bs), 115 fInChannel(nullptr), fOutChannel(nullptr), 116 fNumInputs(-1), fNumOutputs(-1), 117 fRender(0), fCount(count), 118 fSample(sample), fManager(manager), 119 fExit(exit) 120 {} 121 122 dummyaudio_real(int count = BUFFER_TO_RENDER) 123 :fSampleRate(48000), fBufferSize(512), 124 fInChannel(nullptr), fOutChannel(nullptr), 125 fNumInputs(-1), fNumOutputs(-1), 126 fRender(0), fCount(count), 127 fSample(512), fManager(false), 128 fExit(false) 129 {} 130 ~dummyaudio_real()131 virtual ~dummyaudio_real() 132 { 133 for (int i = 0; i < fNumInputs; i++) { 134 delete[] fInChannel[i]; 135 } 136 for (int i = 0; i < fNumOutputs; i++) { 137 delete[] fOutChannel[i]; 138 } 139 delete [] fInChannel; 140 delete [] fOutChannel; 141 } 142 init(const char * name,dsp * dsp)143 virtual bool init(const char* name, dsp* dsp) 144 { 145 fDSP = dsp; 146 147 // To be used in destructor 148 fNumInputs = fDSP->getNumInputs(); 149 fNumOutputs = fDSP->getNumOutputs(); 150 151 fInChannel = new REAL*[fNumInputs]; 152 fOutChannel = new REAL*[fNumOutputs]; 153 154 for (int i = 0; i < fNumInputs; i++) { 155 fInChannel[i] = new REAL[fBufferSize]; 156 memset(fInChannel[i], 0, sizeof(REAL) * fBufferSize); 157 } 158 for (int i = 0; i < fNumOutputs; i++) { 159 fOutChannel[i] = new REAL[fBufferSize]; 160 memset(fOutChannel[i], 0, sizeof(REAL) * fBufferSize); 161 } 162 163 if (fManager) { 164 // classInit is called elsewhere with a custom memory manager 165 fDSP->instanceInit(fSampleRate); 166 } else { 167 fDSP->init(fSampleRate); 168 } 169 170 return true; 171 } 172 start()173 virtual bool start() 174 { 175 fRender = fCount; 176 fRunning = true; 177 if (fCount == INT_MAX) { 178 #ifdef USE_PTHREAD 179 if (pthread_create(&fAudioThread, 0, run, this) != 0) { 180 fRunning = false; 181 } 182 #else 183 fAudioThread = new std::thread(dummyaudio_real::run, this); 184 #endif 185 return fRunning; 186 } else { 187 process(); 188 return true; 189 } 190 } 191 stop()192 virtual void stop() 193 { 194 if (fRunning) { 195 fRunning = false; 196 #ifdef USE_PTHREAD 197 pthread_join(fAudioThread, 0); 198 #else 199 fAudioThread->join(); 200 delete fAudioThread; 201 fAudioThread = 0; 202 #endif 203 } 204 } 205 render()206 void render() 207 { 208 AVOIDDENORMALS; 209 210 fDSP->compute(fBufferSize, reinterpret_cast<FAUSTFLOAT**>(fInChannel), reinterpret_cast<FAUSTFLOAT**>(fOutChannel)); 211 if (fNumInputs > 0) { 212 for (int frame = 0; frame < fSample; frame++) { 213 std::cout << std::fixed << std::setprecision(6) << "sample in " << fInChannel[0][frame] << std::endl; 214 } 215 } 216 if (fNumOutputs > 0) { 217 for (int frame = 0; frame < fSample; frame++) { 218 std::cout << std::fixed << std::setprecision(6) << "sample out " << fOutChannel[0][frame] << std::endl; 219 } 220 } 221 } 222 getBufferSize()223 virtual int getBufferSize() { return fBufferSize; } getSampleRate()224 virtual int getSampleRate() { return fSampleRate; } 225 getNumInputs()226 virtual int getNumInputs() { return fNumInputs; } getNumOutputs()227 virtual int getNumOutputs() { return fNumOutputs; } 228 229 }; 230 231 struct dummyaudio : public dummyaudio_real<FAUSTFLOAT> { 232 233 dummyaudio(int sr, int bs, 234 int count = BUFFER_TO_RENDER, 235 int sample = -1, 236 bool manager = false, 237 bool exit = false) dummyaudio_realdummyaudio238 : dummyaudio_real(sr, bs, count, sample, manager, exit) 239 {} 240 dummyaudio_realdummyaudio241 dummyaudio(int count = BUFFER_TO_RENDER) : dummyaudio_real(count) 242 {} 243 244 }; 245 246 #endif 247 /************************** END dummy-audio.h **************************/ 248