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