1 /************************************************************************
2 ************************************************************************
3 FAUST Architecture File
4 Copyright (C) 2007-2011 Julius O. Smith III
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
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 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 ************************************************************************
21 ************************************************************************/
23 /* matlabplot.cpp = simple variation of plot.cpp */
41 // g++ -O3 -lm -lsndfile myfx.cpp
45 struct Meta
: map
<const char*, const char*>
47 void declare (const char* key
, const char* value
) { (*this)[key
]=value
; }
51 //-------------------------------------------------------------------
52 // Generic min and max using c++ inline
53 //-------------------------------------------------------------------
55 inline int max (unsigned int a
, unsigned int b
) { return (a
>b
) ? a
: b
; }
56 inline int max (int a
, int b
) { return (a
>b
) ? a
: b
; }
58 inline long max (long a
, long b
) { return (a
>b
) ? a
: b
; }
59 inline long max (int a
, long b
) { return (a
>b
) ? a
: b
; }
60 inline long max (long a
, int b
) { return (a
>b
) ? a
: b
; }
62 inline float max (float a
, float b
) { return (a
>b
) ? a
: b
; }
63 inline float max (int a
, float b
) { return (a
>b
) ? a
: b
; }
64 inline float max (float a
, int b
) { return (a
>b
) ? a
: b
; }
65 inline float max (long a
, float b
) { return (a
>b
) ? a
: b
; }
66 inline float max (float a
, long b
) { return (a
>b
) ? a
: b
; }
68 inline double max (double a
, double b
) { return (a
>b
) ? a
: b
; }
69 inline double max (int a
, double b
) { return (a
>b
) ? a
: b
; }
70 inline double max (double a
, int b
) { return (a
>b
) ? a
: b
; }
71 inline double max (long a
, double b
) { return (a
>b
) ? a
: b
; }
72 inline double max (double a
, long b
) { return (a
>b
) ? a
: b
; }
73 inline double max (float a
, double b
) { return (a
>b
) ? a
: b
; }
74 inline double max (double a
, float b
) { return (a
>b
) ? a
: b
; }
77 inline int min (int a
, int b
) { return (a
<b
) ? a
: b
; }
79 inline long min (long a
, long b
) { return (a
<b
) ? a
: b
; }
80 inline long min (int a
, long b
) { return (a
<b
) ? a
: b
; }
81 inline long min (long a
, int b
) { return (a
<b
) ? a
: b
; }
83 inline float min (float a
, float b
) { return (a
<b
) ? a
: b
; }
84 inline float min (int a
, float b
) { return (a
<b
) ? a
: b
; }
85 inline float min (float a
, int b
) { return (a
<b
) ? a
: b
; }
86 inline float min (long a
, float b
) { return (a
<b
) ? a
: b
; }
87 inline float min (float a
, long b
) { return (a
<b
) ? a
: b
; }
89 inline double min (double a
, double b
) { return (a
<b
) ? a
: b
; }
90 inline double min (int a
, double b
) { return (a
<b
) ? a
: b
; }
91 inline double min (double a
, int b
) { return (a
<b
) ? a
: b
; }
92 inline double min (long a
, double b
) { return (a
<b
) ? a
: b
; }
93 inline double min (double a
, long b
) { return (a
<b
) ? a
: b
; }
94 inline double min (float a
, double b
) { return (a
<b
) ? a
: b
; }
95 inline double min (double a
, float b
) { return (a
<b
) ? a
: b
; }
99 inline int lsr (int x
, int n
) { return int(((unsigned int)x
) >> n
); }
101 template<typename T
> T
abs (T a
) { return (a
<T(0)) ? -a
: a
; }
104 /******************************************************************************
105 *******************************************************************************
109 *******************************************************************************
110 *******************************************************************************/
117 /******************************************************************************
118 *******************************************************************************
122 *******************************************************************************
123 *******************************************************************************/
130 UI() : fStopped(false) {}
135 virtual void addButton(const char* label
, float* zone
) = 0;
136 virtual void addToggleButton(const char* label
, float* zone
) = 0;
137 virtual void addCheckButton(const char* label
, float* zone
) = 0;
138 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
139 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
140 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
142 // -- passive widgets
144 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) = 0;
145 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) = 0;
146 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
147 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
149 // -- frames and labels
151 virtual void openFrameBox(const char* label
) = 0;
152 virtual void openTabBox(const char* label
) = 0;
153 virtual void openHorizontalBox(const char* label
) = 0;
154 virtual void openVerticalBox(const char* label
) = 0;
155 virtual void closeBox() = 0;
157 virtual void show() = 0;
158 virtual void run() = 0;
160 void stop() { fStopped
= true; }
161 bool stopped() { return fStopped
; }
163 virtual void declare(float* zone
, const char* key
, const char* value
) {}
170 param(float* z
, float init
, float a
, float b
) : fZone(z
), fMin(a
), fMax(b
) { *z
= init
; }
174 class CMDUI
: public UI
178 vector
<char*> fFiles
;
179 stack
<string
> fPrefix
;
180 map
<string
, param
> fKeyParam
;
182 void openAnyBox(const char* label
)
186 if (label
&& label
[0]) {
187 prefix
= fPrefix
.top() + "-" + label
;
189 prefix
= fPrefix
.top();
191 fPrefix
.push(prefix
);
194 string
simplify(const string
& src
)
207 // Skip the begin of the label "--foo-"
208 // until 3 '-' have been read
209 if (src
[i
]=='-') { level
++; }
213 // copy the content, but skip non alphnum
214 // and content in parenthesis
226 if (isalnum(src
[i
])) {
227 dst
+= tolower(src
[i
]);
234 // here we are inside parenthesis and
235 // we skip the content until we are back to
262 CMDUI(int argc
, char *argv
[]) : UI(), fArgc(argc
), fArgv(argv
) { fPrefix
.push("-"); }
266 void addOption(const char* label
, float* zone
, float init
, float min
, float max
)
268 string fullname
= "-" + simplify(fPrefix
.top() + "-" + label
);
269 fKeyParam
.insert(make_pair(fullname
, param(zone
, init
, min
, max
)));
273 virtual void addButton(const char* label
, float* zone
)
275 addOption(label
,zone
,0,0,1);
278 virtual void addToggleButton(const char* label
, float* zone
)
280 addOption(label
,zone
,0,0,1);
283 virtual void addCheckButton(const char* label
, float* zone
)
285 addOption(label
,zone
,0,0,1);
288 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
290 addOption(label
,zone
,init
,min
,max
);
293 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
295 addOption(label
,zone
,init
,min
,max
);
298 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
300 addOption(label
,zone
,init
,min
,max
);
303 // -- passive widgets
305 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) {}
306 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) {}
307 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) {}
308 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) {}
310 virtual void openFrameBox(const char* label
) { openAnyBox(label
); }
311 virtual void openTabBox(const char* label
) { openAnyBox(label
); }
312 virtual void openHorizontalBox(const char* label
) { openAnyBox(label
); }
313 virtual void openVerticalBox(const char* label
) { openAnyBox(label
); }
315 virtual void closeBox() { fPrefix
.pop(); }
317 virtual void show() {}
318 virtual void run() {}
322 map
<string
, param
>::iterator i
;
323 cout
<< fArgc
<< "\n";
324 cout
<< fArgv
[0] << " option list : ";
325 for (i
= fKeyParam
.begin(); i
!= fKeyParam
.end(); i
++) {
326 cout
<< "[ " << i
->first
<< " " << i
->second
.fMin
<< ".." << i
->second
.fMax
<<" ] ";
328 cout
<< " infile outfile\n";
331 void process_command()
333 map
<string
, param
>::iterator p
;
334 for (int i
= 1; i
< fArgc
; i
++) {
335 if (fArgv
[i
][0] == '-') {
336 if ( (strcmp(fArgv
[i
], "-help") == 0)
337 || (strcmp(fArgv
[i
], "-h") == 0)
338 || (strcmp(fArgv
[i
], "--help") == 0) ) {
342 p
= fKeyParam
.find(fArgv
[i
]);
343 if (p
== fKeyParam
.end()) {
344 cout
<< fArgv
[0] << " : unrecognized option " << fArgv
[i
] << "\n";
349 *(p
->second
.fZone
) = float(strtod(fArgv
[i
+1], &end
));
352 fFiles
.push_back(fArgv
[i
]);
357 int files() { return fFiles
.size(); }
358 char* file (int n
) { return fFiles
[n
]; }
362 //----------------------------------------------------------------
363 // d�inition du processeur de signal
364 //----------------------------------------------------------------
373 virtual int getNumInputs() = 0;
374 virtual int getNumOutputs() = 0;
375 virtual void buildUserInterface(UI
* interface
) = 0;
376 virtual void init(int samplingRate
) = 0;
377 virtual void compute(int len
, float** inputs
, float** outputs
) = 0;
378 virtual void conclude() {}
382 //----------------------------------------------------------------------------
383 // FAUST generated code
384 //----------------------------------------------------------------------------
396 float* fBuffers
[256];
400 channels(int nframes
, int nchannels
)
402 assert(nchannels
< 256);
404 fNumFrames
= nframes
;
405 fNumChannels
= nchannels
;
407 // allocate audio channels
408 for (int i
= 0; i
< fNumChannels
; i
++) {
409 fBuffers
[i
] = (float*) calloc (fNumFrames
, sizeof(float));
415 // allocate audio channels
416 for (int i
= 0; i
< fNumChannels
; i
++) {
417 for (int f
= 0; f
< fNumFrames
; f
++) {
418 fBuffers
[i
][f
] = 0.0;
425 // allocate audio channels
426 for (int i
= 0; i
< fNumChannels
; i
++) {
427 fBuffers
[i
][0] = 1.0;
428 for (int f
= 1; f
< fNumFrames
; f
++) {
429 fBuffers
[i
][f
] = 0.0;
436 // free separate input channels
437 for (int i
= 0; i
< fNumChannels
; i
++) {
442 float** buffers() { return fBuffers
; }
449 int main(int argc
, char *argv
[] )
451 float fStartAtSample
;
455 CMDUI
* interface
= new CMDUI(argc
, argv
);
456 DSP
.buildUserInterface(interface
);
458 interface
->addOption("-s", &fStartAtSample
, 0, 0.0, 100000000.0);
459 interface
->addOption("-n", &fnbsamples
, 16, 0.0, 100000000.0);
461 // if (DSP.getNumInputs() > 0) {
463 // "*** input signals not supported by architecture file matlab.cpp\n");
467 // init signal processor and the user interface values:
470 // modify the UI values according to the command-line options:
471 interface
->process_command();
473 // prepare input channels (if any) with an impulse
474 int nins
= DSP
.getNumInputs();
475 channels
inchan (kFrames
, nins
);
476 inchan
.impulse(); // after each compute we will zero them
478 // prepare output channels
479 int nouts
= DSP
.getNumOutputs();
480 channels
outchan (kFrames
, nouts
);
483 printf("%% Usage: octave --persist thisfile.m\n\n");
485 // print matlab-compatible matrix syntax followed by a plot command:
486 printf("faustout = [ ...\n");
489 // skip <start> samples
490 int start
= int(fStartAtSample
);
491 while (start
> kFrames
) {
492 DSP
.compute(kFrames
, inchan
.buffers(), outchan
.buffers());
497 DSP
.compute(start
, inchan
.buffers(), outchan
.buffers());
502 int nbsamples
= int(fnbsamples
);
503 while (nbsamples
> kFrames
) {
505 DSP
.compute(kFrames
, inchan
.buffers(), outchan
.buffers());
507 for (int i
= 0; i
< kFrames
; i
++) {
508 for (int c
= 0; c
< nouts
; c
++) {
509 printf(" %g", outchan
.buffers()[c
][i
]);
514 printf("; ...\n%%---- Chunk Boundary ----\n");
517 nbsamples
-= kFrames
;
520 if (nbsamples
) { // Write out partial-chunk buffer:
522 DSP
.compute(nbsamples
, inchan
.buffers(), outchan
.buffers());
524 for (int i
= 0; i
< nbsamples
; i
++) {
525 for (int c
= 0; c
< nouts
; c
++) {
526 printf(" %g", outchan
.buffers()[c
][i
]);
532 printf("plot(faustout);\n");
533 printf("title('Plot generated by %s made using ''faust -a matlabplot.cpp ...''');\n",argv
[0]);
534 printf("xlabel('Time (samples)');\n");
535 printf("ylabel('Amplitude');\n");
538 for (int c
= 0; c
< nouts
; c
++) {
539 printf("'channel %d'", c
+1);
540 if (c
<nouts
-1) { printf(","); }