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 #include "audio/dsp.h"
56 /******************************************************************************
57 *******************************************************************************
61 *******************************************************************************
62 *******************************************************************************/
66 /******************************************************************************
67 *******************************************************************************
71 *******************************************************************************
72 *******************************************************************************/
75 float* fZone
; float fMin
; float fMax
;
76 param(float* z
, float init
, float a
, float b
) : fZone(z
), fMin(a
), fMax(b
) { *z
= init
; }
79 class CMDUI
: public UI
84 stack
<string
> fPrefix
;
85 map
<string
, param
> fKeyParam
;
87 void openAnyBox(const char* label
)
91 if (label
&& label
[0]) {
92 prefix
= fPrefix
.top() + "-" + label
;
94 prefix
= fPrefix
.top();
99 string
simplify(const string
& src
)
112 // Skip the begin of the label "--foo-"
113 // until 3 '-' have been read
114 if (src
[i
]=='-') { level
++; }
118 // copy the content, but skip non alphnum
119 // and content in parenthesis
131 if (isalnum(src
[i
])) {
132 dst
+= tolower(src
[i
]);
139 // here we are inside parenthesis and
140 // we skip the content until we are back to
167 CMDUI(int argc
, char *argv
[]) : UI(), fArgc(argc
), fArgv(argv
) { fPrefix
.push("-"); }
171 void addOption(const char* label
, float* zone
, float init
, float min
, float max
)
173 string fullname
= "-" + simplify(fPrefix
.top() + "-" + label
);
174 fKeyParam
.insert(make_pair(fullname
, param(zone
, init
, min
, max
)));
178 virtual void addButton(const char* label
, float* zone
)
180 addOption(label
,zone
,0,0,1);
183 virtual void addToggleButton(const char* label
, float* zone
)
185 addOption(label
,zone
,0,0,1);
188 virtual void addCheckButton(const char* label
, float* zone
)
190 addOption(label
,zone
,0,0,1);
193 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
195 addOption(label
,zone
,init
,min
,max
);
198 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
200 addOption(label
,zone
,init
,min
,max
);
203 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
205 addOption(label
,zone
,init
,min
,max
);
208 // -- passive widgets
210 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) {}
211 virtual void addTextDisplay(const char* label
, float* zone
, const char* names
[], float min
, float max
) {}
212 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) {}
213 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) {}
215 virtual void openFrameBox(const char* label
) { openAnyBox(label
); }
216 virtual void openTabBox(const char* label
) { openAnyBox(label
); }
217 virtual void openHorizontalBox(const char* label
) { openAnyBox(label
); }
218 virtual void openVerticalBox(const char* label
) { openAnyBox(label
); }
220 virtual void closeBox() { fPrefix
.pop(); }
222 virtual void show() {}
223 virtual void run() {}
227 map
<string
, param
>::iterator i
;
228 cout
<< fArgc
<< "\n";
229 cout
<< fArgv
[0] << " option list : ";
230 for (i
= fKeyParam
.begin(); i
!= fKeyParam
.end(); i
++) {
231 cout
<< "[ " << i
->first
<< " " << i
->second
.fMin
<< ".." << i
->second
.fMax
<<" ] ";
233 cout
<< " infile outfile\n";
236 void process_command()
238 map
<string
, param
>::iterator p
;
239 for (int i
= 1; i
< fArgc
; i
++) {
240 if (fArgv
[i
][0] == '-') {
241 if ( (strcmp(fArgv
[i
], "-help") == 0)
242 || (strcmp(fArgv
[i
], "-h") == 0)
243 || (strcmp(fArgv
[i
], "--help") == 0) ) {
247 p
= fKeyParam
.find(fArgv
[i
]);
248 if (p
== fKeyParam
.end()) {
249 cout
<< fArgv
[0] << " : unrecognized option " << fArgv
[i
] << "\n";
254 *(p
->second
.fZone
) = float(strtod(fArgv
[i
+1], &end
));
257 fFiles
.push_back(fArgv
[i
]);
262 int files() { return fFiles
.size(); }
263 char* file (int n
) { return fFiles
[n
]; }
265 char* input_file () { cout
<< "input file " << fFiles
[0]; return fFiles
[0]; }
266 char* output_file() { cout
<< "output file " << fFiles
[1]; return fFiles
[1]; }
270 map
<string
, param
>::iterator p
;
271 for (int i
= 1; i
< fArgc
; i
++) {
272 if (fArgv
[i
][0] == '-') {
273 p
= fKeyParam
.find(fArgv
[i
]);
274 if (p
== fKeyParam
.end()) {
275 cout
<< fArgv
[0] << " : unrecognized option " << fArgv
[i
] << "\n";
279 *(p
->second
.fZone
) = float(strtod(fArgv
[i
+1], &end
));
286 /********************END ARCHITECTURE SECTION (part 1/2)****************/
288 /**************************BEGIN USER SECTION **************************/
292 /***************************END USER SECTION ***************************/
294 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
306 float* fOutputs
[256];
310 Separator(int numFrames
, int numInputs
, int numOutputs
)
312 fNumFrames
= numFrames
;
313 fNumInputs
= numInputs
;
314 fNumOutputs
= max(numInputs
, numOutputs
);
316 // allocate interleaved input channel
317 fInput
= (float*) calloc(fNumFrames
*fNumInputs
, sizeof(float));
319 // allocate separate output channels
320 for (int i
= 0; i
< fNumOutputs
; i
++) {
321 fOutputs
[i
] = (float*) calloc (fNumFrames
, sizeof(float));
327 // free interleaved input channel
330 // free separate output channels
331 for (int i
= 0; i
< fNumOutputs
; i
++) {
336 float* input() { return fInput
; }
338 float** outputs() { return fOutputs
; }
342 for (int s
= 0; s
< fNumFrames
; s
++) {
343 for (int c
= 0; c
< fNumInputs
; c
++) {
344 fOutputs
[c
][s
] = fInput
[c
+ s
*fNumInputs
];
361 Interleaver(int numFrames
, int numInputs
, int numOutputs
)
363 fNumFrames
= numFrames
;
364 fNumInputs
= max(numInputs
, numOutputs
);
365 fNumOutputs
= numOutputs
;
367 // allocate separate input channels
368 for (int i
= 0; i
< fNumInputs
; i
++) {
369 fInputs
[i
] = (float*) calloc (fNumFrames
, sizeof(float));
372 // allocate interleaved output channel
373 fOutput
= (float*) calloc(fNumFrames
*fNumOutputs
, sizeof(float));
379 // free separate input channels
380 for (int i
= 0; i
< fNumInputs
; i
++) {
384 // free interleaved output channel
388 float** inputs() { return fInputs
; }
390 float* output() { return fOutput
; }
394 for (int s
= 0; s
< fNumFrames
; s
++) {
395 for (int c
= 0; c
< fNumOutputs
; c
++) {
396 fOutput
[c
+ s
*fNumOutputs
] = fInputs
[c
][s
];
404 int main(int argc
, char *argv
[] )
411 CMDUI
* interface
= new CMDUI(argc
, argv
);
412 DSP
.buildUserInterface(interface
);
413 interface
->process_command();
417 in_sf
= sf_open (interface
->input_file(), SFM_READ
, &in_info
);
418 if (in_sf
== NULL
) { sf_perror(in_sf
); exit(0); }
422 out_info
.format
= in_info
.format
;
423 out_info
.channels
= DSP
.getNumOutputs();
424 out_sf
= sf_open(interface
->output_file(), SFM_WRITE
, &out_info
);
425 if (out_sf
== NULL
) { sf_perror(out_sf
); exit(0); }
428 // create separator and interleaver
429 Separator
sep (kFrames
, in_info
.channels
, DSP
.getNumInputs());
430 Interleaver
ilv (kFrames
, DSP
.getNumOutputs(), DSP
.getNumOutputs());
432 // init signal processor
433 DSP
.init(in_info
.samplerate
);
434 //DSP.buildUserInterface(interface);
435 interface
->process_init();
437 // process all samples
440 nbf
= sf_readf_float(in_sf
, sep
.input(), kFrames
);
442 DSP
.compute(nbf
, sep
.outputs(), ilv
.inputs());
444 sf_writef_float(out_sf
, ilv
.output(), nbf
);
445 //sf_write_raw(out_sf, ilv.output(), nbf);
446 } while (nbf
== kFrames
);
448 // close the input and output files
453 /********************END ARCHITECTURE SECTION (part 2/2)****************/