1 /************************************************************************
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 *************************************************************************/
9 /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
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.
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.
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/>.
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.
34 ************************************************************************
35 ************************************************************************/
53 // g++ -O3 -lm -lsndfile myfx.cpp
57 struct Meta
: map
<const char*, const char*>
59 void declare (const char* key
, const char* value
) { (*this)[key
]=value
; }
62 //-------------------------------------------------------------------
63 // Generic min and max using c++ inline
64 //-------------------------------------------------------------------
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
; }
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
; }
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
; }
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
; }
88 inline int min (int a
, int b
) { return (a
<b
) ? a
: b
; }
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
; }
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
; }
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
; }
110 inline int lsr (int x
, int n
) { return int(((unsigned int)x
) >> n
); }
112 template<typename T
> T
abs (T a
) { return (a
<T(0)) ? -a
: a
; }
115 /******************************************************************************
116 *******************************************************************************
120 *******************************************************************************
121 *******************************************************************************/
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); }
131 /******************************************************************************
132 *******************************************************************************
136 *******************************************************************************
137 *******************************************************************************/
144 UI() : fStopped(false) {}
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;
156 // -- passive widgets
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;
163 // -- frames and labels
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;
171 virtual void show() = 0;
172 virtual void run() = 0;
174 void stop() { fStopped
= true; }
175 bool stopped() { return fStopped
; }
177 virtual void declare(float* zone
, const char* key
, const char* value
) {}
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
; }
186 class CMDUI
: public UI
190 vector
<char*> fFiles
;
191 stack
<string
> fPrefix
;
192 map
<string
, param
> fKeyParam
;
194 void openAnyBox(const char* label
)
198 if (label
&& label
[0]) {
199 prefix
= fPrefix
.top() + "-" + label
;
201 prefix
= fPrefix
.top();
203 fPrefix
.push(prefix
);
206 string
simplify(const string
& src
)
219 // Skip the begin of the label "--foo-"
220 // until 3 '-' have been read
221 if (src
[i
]=='-') { level
++; }
225 // copy the content, but skip non alphnum
226 // and content in parenthesis
238 if (isalnum(src
[i
])) {
239 dst
+= tolower(src
[i
]);
246 // here we are inside parenthesis and
247 // we skip the content until we are back to
274 CMDUI(int argc
, char *argv
[]) : UI(), fArgc(argc
), fArgv(argv
) { fPrefix
.push("-"); }
278 void addOption(const char* label
, float* zone
, float init
, float min
, float max
)
280 string fullname
= "-" + simplify(fPrefix
.top() + "-" + label
);
281 fKeyParam
.insert(make_pair(fullname
, param(zone
, init
, min
, max
)));
285 virtual void addButton(const char* label
, float* zone
)
287 addOption(label
,zone
,0,0,1);
290 virtual void addToggleButton(const char* label
, float* zone
)
292 addOption(label
,zone
,0,0,1);
295 virtual void addCheckButton(const char* label
, float* zone
)
297 addOption(label
,zone
,0,0,1);
300 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
302 addOption(label
,zone
,init
,min
,max
);
305 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
307 addOption(label
,zone
,init
,min
,max
);
310 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
312 addOption(label
,zone
,init
,min
,max
);
315 // -- passive widgets
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
) {}
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
); }
327 virtual void closeBox() { fPrefix
.pop(); }
329 virtual void show() {}
330 virtual void run() {}
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
<<" ] ";
340 cout
<< " infile outfile\n";
343 void process_command()
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) ) {
354 p
= fKeyParam
.find(fArgv
[i
]);
355 if (p
== fKeyParam
.end()) {
356 cout
<< fArgv
[0] << " : unrecognized option " << fArgv
[i
] << "\n";
361 *(p
->second
.fZone
) = float(strtod(fArgv
[i
+1], &end
));
364 fFiles
.push_back(fArgv
[i
]);
369 int files() { return fFiles
.size(); }
370 char* file (int n
) { return fFiles
[n
]; }
374 //----------------------------------------------------------------
375 // d�inition du processeur de signal
376 //----------------------------------------------------------------
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() {}
393 /********************END ARCHITECTURE SECTION (part 1/2)****************/
395 /**************************BEGIN USER SECTION **************************/
399 /***************************END USER SECTION ***************************/
401 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
410 float* fBuffers
[256];
414 channels(int nframes
, int nchannels
)
416 fNumFrames
= nframes
;
417 fNumChannels
= nchannels
;
419 // allocate audio channels
420 for (int i
= 0; i
< fNumChannels
; i
++) {
421 fBuffers
[i
] = (float*) calloc (fNumFrames
, sizeof(float));
427 // free separate input channels
428 for (int i
= 0; i
< fNumChannels
; i
++) {
429 // free(fBuffers[i]);
433 float** buffers() { return fBuffers
; }
440 int main(int argc
, char *argv
[] )
445 CMDUI
* interface
= new CMDUI(argc
, argv
);
446 DSP
.buildUserInterface(interface
);
447 interface
->addOption("-n", &fnbsamples
, 16, 0.0, 100000000.0);
449 if (DSP
.getNumInputs() > 0) {
450 fprintf(stderr
, "no inputs allowed\n");
454 // init signal processor and the user interface values
457 // modifie the UI valuez according to the command line options
458 interface
->process_command();
460 int nouts
= DSP
.getNumOutputs();
461 channels
chan (kFrames
, nouts
);
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
]);
472 nbsamples
-= kFrames
;
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
]);
484 /********************END ARCHITECTURE SECTION (part 2/2)****************/