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 -lsynthfile myfx.cpp
57 struct Meta
: map
<const char*, const char*>
59 void declare (const char* key
, const char* value
) { (*this)[key
]=value
; }
63 #define max(x,y) (((x)>(y)) ? (x) : (y))
64 #define min(x,y) (((x)<(y)) ? (x) : (y))
66 // abs is now predefined
67 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
70 inline int lsr (int x
, int n
) { return int(((unsigned int)x
) >> n
); }
73 /******************************************************************************
74 *******************************************************************************
78 *******************************************************************************
79 *******************************************************************************/
87 /******************************************************************************
88 *******************************************************************************
92 *******************************************************************************
93 *******************************************************************************/
100 UI() : fStopped(false) {}
105 virtual void addButton(const char* label
, float* zone
) = 0;
106 virtual void addToggleButton(const char* label
, float* zone
) = 0;
107 virtual void addCheckButton(const char* label
, float* zone
) = 0;
108 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
109 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
110 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
112 // -- passive widgets
114 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) = 0;
115 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) = 0;
116 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
117 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
119 // -- frames and labels
121 virtual void openFrameBox(const char* label
) = 0;
122 virtual void openTabBox(const char* label
) = 0;
123 virtual void openHorizontalBox(const char* label
) = 0;
124 virtual void openVerticalBox(const char* label
) = 0;
125 virtual void closeBox() = 0;
127 virtual void show() = 0;
128 virtual void run() = 0;
130 void stop() { fStopped
= true; }
131 bool stopped() { return fStopped
; }
133 virtual void declare(float* zone
, const char* key
, const char* value
) {}
137 float* fZone
; float fMin
; float fMax
;
138 param(float* z
, float init
, float a
, float b
) : fZone(z
), fMin(a
), fMax(b
) { *z
= init
; }
142 class CMDUI
: public UI
148 stack
<string
> fPrefix
;
149 map
<string
, param
> fKeyParam
;
151 void openAnyBox(const char* label
)
155 if (label
&& label
[0]) {
156 prefix
= fPrefix
.top() + "-" + label
;
158 prefix
= fPrefix
.top();
160 fPrefix
.push(prefix
);
163 string
simplify(const string
& src
)
176 // Skip the begin of the label "--foo-"
177 // until 3 '-' have been read
178 if (src
[i
]=='-') { level
++; }
182 // copy the content, but skip non alphnum
183 // and content in parenthesis
195 if (isalnum(src
[i
])) {
196 dst
+= tolower(src
[i
]);
203 // here we are inside parenthesis and
204 // we skip the content until we are back to
231 CMDUI(int argc
, char *argv
[]) : UI(), fArgc(argc
), fArgv(argv
), fNumframes(44100), fOutFile("out.wav")
232 { fPrefix
.push("-"); }
236 void addOption(const char* label
, float* zone
, float init
, float min
, float max
)
238 string fullname
= "-" + simplify(fPrefix
.top() + "-" + label
);
239 fKeyParam
.insert(make_pair(fullname
, param(zone
, init
, min
, max
)));
243 virtual void addButton(const char* label
, float* zone
)
245 addOption(label
,zone
,0,0,1);
248 virtual void addToggleButton(const char* label
, float* zone
)
250 addOption(label
,zone
,0,0,1);
253 virtual void addCheckButton(const char* label
, float* zone
)
255 addOption(label
,zone
,0,0,1);
258 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
260 addOption(label
,zone
,init
,min
,max
);
263 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
265 addOption(label
,zone
,init
,min
,max
);
268 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
270 addOption(label
,zone
,init
,min
,max
);
273 // -- passive widgets
275 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) {}
276 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) {}
277 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) {}
278 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) {}
280 virtual void openFrameBox(const char* label
) { openAnyBox(label
); }
281 virtual void openTabBox(const char* label
) { openAnyBox(label
); }
282 virtual void openHorizontalBox(const char* label
) { openAnyBox(label
); }
283 virtual void openVerticalBox(const char* label
) { openAnyBox(label
); }
285 virtual void closeBox() { fPrefix
.pop(); }
287 virtual void show() {}
288 virtual void run() {}
292 cerr
<< "usage: " << fArgv
[0] << " [options]" << endl
;
293 cerr
<< " [options]: " << endl
;
294 cerr
<< " samples: number of samples to generate, default is 44100 (1 second of sound)" << endl
;
295 cerr
<< " -o outfile: name of the output file, default is 'out.wav'" << endl
;
297 if (fKeyParam
.size()) {
298 map
<string
, param
>::iterator i
;
299 cerr
<< " [faust module options]: \n";
300 for (i
= fKeyParam
.begin(); i
!= fKeyParam
.end(); i
++) {
301 cout
<< " " << i
->first
<< " [" << i
->second
.fMin
<< ".." << i
->second
.fMax
<<" ] \n";
307 void process_command()
309 map
<string
, param
>::iterator p
;
311 for (int i
= 1; i
< fArgc
; i
++) {
312 if (fArgv
[i
][0] == '-') {
313 if ( (strcmp(fArgv
[i
], "-help") == 0)
314 || (strcmp(fArgv
[i
], "-h") == 0)
315 || (strcmp(fArgv
[i
], "--help") == 0) ) {
319 if (strcmp(fArgv
[i
], "-o") == 0) {
320 fOutFile
= fArgv
[i
+1];
323 p
= fKeyParam
.find(fArgv
[i
]);
324 if (p
== fKeyParam
.end()) {
325 cout
<< fArgv
[0] << ": unrecognized option " << fArgv
[i
] << "\n";
328 *(p
->second
.fZone
) = float(strtod(fArgv
[i
+1], NULL
));
333 fNumframes
= strtol(fArgv
[i
], NULL
, 10);
334 if (fNumframes
<= 0 ) printhelp();
339 char* output_file() { return fOutFile
; }
340 long num_frames() { return fNumframes
; }
344 map
<string
, param
>::iterator p
;
345 for (int i
= 1; i
< fArgc
; i
++) {
346 if (fArgv
[i
][0] == '-') {
347 p
= fKeyParam
.find(fArgv
[i
]);
348 if (p
!= fKeyParam
.end()) {
349 *(p
->second
.fZone
) = float(strtod(fArgv
[i
+1], NULL
));
358 //----------------------------------------------------------------
359 // d�inition du processeur de signal
360 //----------------------------------------------------------------
369 virtual int getNumInputs() = 0;
370 virtual int getNumOutputs() = 0;
371 virtual void buildUserInterface(UI
* interface
) = 0;
372 virtual void init(int samplingRate
) = 0;
373 virtual void compute(int len
, float** inputs
, float** outputs
) = 0;
374 virtual void conclude() {}
377 /********************END ARCHITECTURE SECTION (part 1/2)****************/
379 /**************************BEGIN USER SECTION **************************/
383 /***************************END USER SECTION ***************************/
385 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
400 Interleaver(int numFrames
, int numInputs
, int numOutputs
)
402 fNumFrames
= numFrames
;
403 fNumInputs
= max(numInputs
, numOutputs
);
404 fNumOutputs
= numOutputs
;
406 // allocate separate input channels
407 for (int i
= 0; i
< fNumInputs
; i
++) {
408 fInputs
[i
] = (float*) calloc (fNumFrames
, sizeof(float));
411 // allocate interleaved output channel
412 fOutput
= (float*) calloc(fNumFrames
*fNumOutputs
, sizeof(float));
418 // free separate input channels
419 for (int i
= 0; i
< fNumInputs
; i
++) {
423 // free interleaved output channel
427 float** inputs() { return fInputs
; }
428 float* output() { return fOutput
; }
432 for (int s
= 0; s
< fNumFrames
; s
++) {
433 for (int c
= 0; c
< fNumOutputs
; c
++) {
434 fOutput
[c
+ s
*fNumOutputs
] = fInputs
[c
][s
];
441 #define kSampleRate 44100
443 int main(int argc
, char *argv
[] )
445 CMDUI
* interface
= new CMDUI(argc
, argv
);
446 DSP
.buildUserInterface(interface
);
447 interface
->process_command();
451 SF_INFO out_info
= { interface
->num_frames(), kSampleRate
, DSP
.getNumOutputs(),
452 SF_FORMAT_WAV
|SF_FORMAT_PCM_16
|SF_ENDIAN_LITTLE
, 0, 0};
453 out_sf
= sf_open(interface
->output_file(), SFM_WRITE
, &out_info
);
454 if (out_sf
== NULL
) {
460 // create interleaver
461 Interleaver
ilv (kFrames
, DSP
.getNumOutputs(), DSP
.getNumOutputs());
463 // init signal processor
464 DSP
.init(kSampleRate
);
465 interface
->process_init();
467 // process all samples
468 int frames
= interface
->num_frames();
471 if (frames
> kFrames
) {
479 DSP
.compute(nbf
, 0, ilv
.inputs());
481 sf_writef_float(out_sf
, ilv
.output(), nbf
);
486 /********************END ARCHITECTURE SECTION (part 2/2)****************/