User Manual first draft.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / architecture / plot.cpp
1 /************************************************************************
2
3 IMPORTANT NOTE : this file contains two clearly delimited sections :
4 the ARCHITECTURE section (in two parts) and the USER section. Each section
5 is governed by its own copyright and license. Please check individually
6 each section for license and copyright information.
7 *************************************************************************/
8
9 /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
10
11 /************************************************************************
12 FAUST Architecture File
13 Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
14 ---------------------------------------------------------------------
15 This Architecture section is free software; you can redistribute it
16 and/or modify it under the terms of the GNU General Public License
17 as published by the Free Software Foundation; either version 3 of
18 the License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; If not, see <http://www.gnu.org/licenses/>.
27
28 EXCEPTION : As a special exception, you may create a larger work
29 that contains this FAUST architecture section and distribute
30 that work under terms of your choice, so long as this FAUST
31 architecture section is not modified.
32
33
34 ************************************************************************
35 ************************************************************************/
36
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <limits.h>
42 #include <math.h>
43 #include <errno.h>
44 #include <time.h>
45 #include <ctype.h>
46
47 #include <vector>
48 #include <stack>
49 #include <string>
50 #include <map>
51 #include <iostream>
52
53 // g++ -O3 -lm -lsndfile myfx.cpp
54
55 using namespace std;
56
57 struct Meta : map<const char*, const char*>
58 {
59 void declare (const char* key, const char* value) { (*this)[key]=value; }
60 };
61
62 //-------------------------------------------------------------------
63 // Generic min and max using c++ inline
64 //-------------------------------------------------------------------
65
66 inline int max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
67 inline int max (int a, int b) { return (a>b) ? a : b; }
68
69 inline long max (long a, long b) { return (a>b) ? a : b; }
70 inline long max (int a, long b) { return (a>b) ? a : b; }
71 inline long max (long a, int b) { return (a>b) ? a : b; }
72
73 inline float max (float a, float b) { return (a>b) ? a : b; }
74 inline float max (int a, float b) { return (a>b) ? a : b; }
75 inline float max (float a, int b) { return (a>b) ? a : b; }
76 inline float max (long a, float b) { return (a>b) ? a : b; }
77 inline float max (float a, long b) { return (a>b) ? a : b; }
78
79 inline double max (double a, double b) { return (a>b) ? a : b; }
80 inline double max (int a, double b) { return (a>b) ? a : b; }
81 inline double max (double a, int b) { return (a>b) ? a : b; }
82 inline double max (long a, double b) { return (a>b) ? a : b; }
83 inline double max (double a, long b) { return (a>b) ? a : b; }
84 inline double max (float a, double b) { return (a>b) ? a : b; }
85 inline double max (double a, float b) { return (a>b) ? a : b; }
86
87
88 inline int min (int a, int b) { return (a<b) ? a : b; }
89
90 inline long min (long a, long b) { return (a<b) ? a : b; }
91 inline long min (int a, long b) { return (a<b) ? a : b; }
92 inline long min (long a, int b) { return (a<b) ? a : b; }
93
94 inline float min (float a, float b) { return (a<b) ? a : b; }
95 inline float min (int a, float b) { return (a<b) ? a : b; }
96 inline float min (float a, int b) { return (a<b) ? a : b; }
97 inline float min (long a, float b) { return (a<b) ? a : b; }
98 inline float min (float a, long b) { return (a<b) ? a : b; }
99
100 inline double min (double a, double b) { return (a<b) ? a : b; }
101 inline double min (int a, double b) { return (a<b) ? a : b; }
102 inline double min (double a, int b) { return (a<b) ? a : b; }
103 inline double min (long a, double b) { return (a<b) ? a : b; }
104 inline double min (double a, long b) { return (a<b) ? a : b; }
105 inline double min (float a, double b) { return (a<b) ? a : b; }
106 inline double min (double a, float b) { return (a<b) ? a : b; }
107
108
109
110 inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
111
112 template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
113
114
115 /******************************************************************************
116 *******************************************************************************
117
118 VECTOR INTRINSICS
119
120 *******************************************************************************
121 *******************************************************************************/
122
123 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
124 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
125
126 <<includeIntrinsic>>
127
128
129
130
131 /******************************************************************************
132 *******************************************************************************
133
134 USER INTERFACE
135
136 *******************************************************************************
137 *******************************************************************************/
138
139 class UI
140 {
141 bool fStopped;
142 public:
143
144 UI() : fStopped(false) {}
145 virtual ~UI() {}
146
147 // -- active widgets
148
149 virtual void addButton(const char* label, float* zone) = 0;
150 virtual void addToggleButton(const char* label, float* zone) = 0;
151 virtual void addCheckButton(const char* label, float* zone) = 0;
152 virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
153 virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
154 virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
155
156 // -- passive widgets
157
158 virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
159 virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
160 virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
161 virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
162
163 // -- frames and labels
164
165 virtual void openFrameBox(const char* label) = 0;
166 virtual void openTabBox(const char* label) = 0;
167 virtual void openHorizontalBox(const char* label) = 0;
168 virtual void openVerticalBox(const char* label) = 0;
169 virtual void closeBox() = 0;
170
171 virtual void show() = 0;
172 virtual void run() = 0;
173
174 void stop() { fStopped = true; }
175 bool stopped() { return fStopped; }
176
177 virtual void declare(float* zone, const char* key, const char* value) {}
178 };
179
180 struct param {
181 float* fZone; float fMin; float fMax;
182 param(float* z, float init, float a, float b) : fZone(z), fMin(a), fMax(b) { *z = init; }
183 };
184
185
186 class CMDUI : public UI
187 {
188 int fArgc;
189 char** fArgv;
190 vector<char*> fFiles;
191 stack<string> fPrefix;
192 map<string, param> fKeyParam;
193
194 void openAnyBox(const char* label)
195 {
196 string prefix;
197
198 if (label && label[0]) {
199 prefix = fPrefix.top() + "-" + label;
200 } else {
201 prefix = fPrefix.top();
202 }
203 fPrefix.push(prefix);
204 }
205
206 string simplify(const string& src)
207 {
208 int i=0;
209 int level=0;
210 string dst;
211
212 while (src[i] ) {
213
214 switch (level) {
215
216 case 0 :
217 case 1 :
218 case 2 :
219 // Skip the begin of the label "--foo-"
220 // until 3 '-' have been read
221 if (src[i]=='-') { level++; }
222 break;
223
224 case 3 :
225 // copy the content, but skip non alphnum
226 // and content in parenthesis
227 switch (src[i]) {
228 case '(' :
229 case '[' :
230 level++;
231 break;
232
233 case '-' :
234 dst += '-';
235 break;
236
237 default :
238 if (isalnum(src[i])) {
239 dst+= tolower(src[i]);
240 }
241
242 }
243 break;
244
245 default :
246 // here we are inside parenthesis and
247 // we skip the content until we are back to
248 // level 3
249 switch (src[i]) {
250
251 case '(' :
252 case '[' :
253 level++;
254 break;
255
256 case ')' :
257 case ']' :
258 level--;
259 break;
260
261 default :
262 break;
263 }
264
265 }
266 i++;
267 }
268 return dst;
269 }
270
271
272 public:
273
274 CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("-"); }
275 virtual ~CMDUI() {}
276
277
278 void addOption(const char* label, float* zone, float init, float min, float max)
279 {
280 string fullname = "-" + simplify(fPrefix.top() + "-" + label);
281 fKeyParam.insert(make_pair(fullname, param(zone, init, min, max)));
282 }
283
284
285 virtual void addButton(const char* label, float* zone)
286 {
287 addOption(label,zone,0,0,1);
288 }
289
290 virtual void addToggleButton(const char* label, float* zone)
291 {
292 addOption(label,zone,0,0,1);
293 }
294
295 virtual void addCheckButton(const char* label, float* zone)
296 {
297 addOption(label,zone,0,0,1);
298 }
299
300 virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
301 {
302 addOption(label,zone,init,min,max);
303 }
304
305 virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
306 {
307 addOption(label,zone,init,min,max);
308 }
309
310 virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
311 {
312 addOption(label,zone,init,min,max);
313 }
314
315 // -- passive widgets
316
317 virtual void addNumDisplay(const char* label, float* zone, int precision) {}
318 virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {}
319 virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {}
320 virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) {}
321
322 virtual void openFrameBox(const char* label) { openAnyBox(label); }
323 virtual void openTabBox(const char* label) { openAnyBox(label); }
324 virtual void openHorizontalBox(const char* label) { openAnyBox(label); }
325 virtual void openVerticalBox(const char* label) { openAnyBox(label); }
326
327 virtual void closeBox() { fPrefix.pop(); }
328
329 virtual void show() {}
330 virtual void run() {}
331
332 void printhelp()
333 {
334 map<string, param>::iterator i;
335 cout << fArgc << "\n";
336 cout << fArgv[0] << " option list : ";
337 for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) {
338 cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
339 }
340 cout << " infile outfile\n";
341 }
342
343 void process_command()
344 {
345 map<string, param>::iterator p;
346 for (int i = 1; i < fArgc; i++) {
347 if (fArgv[i][0] == '-') {
348 if ( (strcmp(fArgv[i], "-help") == 0)
349 || (strcmp(fArgv[i], "-h") == 0)
350 || (strcmp(fArgv[i], "--help") == 0) ) {
351 printhelp();
352 exit(1);
353 }
354 p = fKeyParam.find(fArgv[i]);
355 if (p == fKeyParam.end()) {
356 cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
357 printhelp();
358 exit(1);
359 }
360 char* end;
361 *(p->second.fZone) = float(strtod(fArgv[i+1], &end));
362 i++;
363 } else {
364 fFiles.push_back(fArgv[i]);
365 }
366 }
367 }
368
369 int files() { return fFiles.size(); }
370 char* file (int n) { return fFiles[n]; }
371
372 };
373
374 //----------------------------------------------------------------
375 // d�inition du processeur de signal
376 //----------------------------------------------------------------
377
378 class dsp {
379 protected:
380 int fSamplingFreq;
381 public:
382 dsp() {}
383 virtual ~dsp() {}
384
385 virtual int getNumInputs() = 0;
386 virtual int getNumOutputs() = 0;
387 virtual void buildUserInterface(UI* interface) = 0;
388 virtual void init(int samplingRate) = 0;
389 virtual void compute(int len, float** inputs, float** outputs) = 0;
390 virtual void conclude() {}
391 };
392
393 /********************END ARCHITECTURE SECTION (part 1/2)****************/
394
395 /**************************BEGIN USER SECTION **************************/
396
397 <<includeclass>>
398
399 /***************************END USER SECTION ***************************/
400
401 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
402
403 mydsp DSP;
404
405
406 class channels
407 {
408 int fNumFrames;
409 int fNumChannels;
410 float* fBuffers[256];
411
412 public:
413
414 channels(int nframes, int nchannels)
415 {
416 fNumFrames = nframes;
417 fNumChannels = nchannels;
418
419 // allocate audio channels
420 for (int i = 0; i < fNumChannels; i++) {
421 fBuffers[i] = (float*) calloc (fNumFrames, sizeof(float));
422 }
423 }
424
425 ~channels()
426 {
427 // free separate input channels
428 for (int i = 0; i < fNumChannels; i++) {
429 // free(fBuffers[i]);
430 }
431 }
432
433 float** buffers() { return fBuffers; }
434 };
435
436
437
438 #define kFrames 512
439
440 int main(int argc, char *argv[] )
441 {
442 float fnbsamples;
443
444
445 CMDUI* interface = new CMDUI(argc, argv);
446 DSP.buildUserInterface(interface);
447 interface->addOption("-n", &fnbsamples, 16, 0.0, 100000000.0);
448
449 if (DSP.getNumInputs() > 0) {
450 fprintf(stderr, "no inputs allowed\n");
451 exit(1);
452 }
453
454 // init signal processor and the user interface values
455 DSP.init(44100);
456
457 // modifie the UI valuez according to the command line options
458 interface->process_command();
459
460 int nouts = DSP.getNumOutputs();
461 channels chan (kFrames, nouts);
462
463 int nbsamples = int(fnbsamples);
464 while (nbsamples > kFrames) {
465 DSP.compute(kFrames, 0, chan.buffers());
466 for (int i = 0; i < kFrames; i++) {
467 for (int c = 0; c < nouts; c++) {
468 printf("%8f\t", chan.buffers()[c][i]);
469 }
470 cout << endl;
471 }
472 nbsamples -= kFrames;
473 }
474
475 DSP.compute(nbsamples, 0, chan.buffers());
476 for (int i = 0; i < nbsamples; i++) {
477 for (int c = 0; c < nouts; c++) {
478 printf("%8f\t", chan.buffers()[c][i]);
479 }
480 cout << endl;
481 }
482 return 0;
483 }
484 /********************END ARCHITECTURE SECTION (part 2/2)****************/
485
486