2 Copyright (C) 2009 by Bjoern Anton Erlach. */
4 // OCTAVE architecture file for faust.
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License as
8 // published by the Free Software Foundation; either version 2 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 GNU
14 // General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 //-------------------------------------------------------------------
39 // TODO: find out what to do with this Meta thing
40 struct Meta
: map
<const char*, const char*>
42 void declare (const char* key
, const char* value
) { (*this)[key
]=value
; }
46 #define max(x,y) (((x)>(y)) ? (x) : (y))
47 #define min(x,y) (((x)<(y)) ? (x) : (y))
49 // abs is now predefined
50 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
53 inline int lsr (int x
, int n
) { return int(((unsigned int)x
) >> n
); }
55 /******************************************************************************
56 *******************************************************************************
60 *******************************************************************************
61 *******************************************************************************/
63 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
64 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
69 /******************************************************************************
70 *******************************************************************************
72 ABSTRACT USER INTERFACE
74 *******************************************************************************
75 *******************************************************************************/
83 UI() : fStopped(false) {}
88 virtual void addButton(const char* label
, float* zone
) = 0;
89 virtual void addToggleButton(const char* label
, float* zone
) = 0;
90 virtual void addCheckButton(const char* label
, float* zone
) = 0;
91 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
92 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
93 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
97 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) = 0;
98 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) = 0;
99 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
100 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
102 // -- frames and labels
104 virtual void openFrameBox(const char* label
) = 0;
105 virtual void openTabBox(const char* label
) = 0;
106 virtual void openHorizontalBox(const char* label
) = 0;
107 virtual void openVerticalBox(const char* label
) = 0;
108 virtual void closeBox() = 0;
110 virtual void show() = 0;
111 virtual void run() = 0;
113 void stop() { fStopped
= true; }
114 bool stopped() { return fStopped
; }
116 virtual void declare(float* zone
, const char* key
, const char* value
) {}
121 string fName
; float *fVals
; float* fZone
; float fMin
; float fMax
;
122 param(string name
, float* z
, float init
, float a
, float b
) : fName(name
), fVals(NULL
), fZone(z
), fMin(a
), fMax(b
) { *z
= init
; }
126 class FNUI
: public UI
128 vector
<param
> fParam
;
133 FNUI() : UI() { numOptions
=0; }
137 void addOption(const char* label
, float* zone
, float init
, float min
, float max
)
139 string fullname
= label
;
140 fParam
.push_back(param(fullname
, zone
, init
, min
, max
));
144 virtual vector
<param
> getOpts () { return fParam
; }
146 virtual void addButton(const char* label
, float* zone
)
148 addOption(label
,zone
,0,0,1);
151 virtual int getNumOptions() { return numOptions
; }
153 virtual void addToggleButton(const char* label
, float* zone
)
155 addOption(label
,zone
,0,0,1);
158 virtual void addCheckButton(const char* label
, float* zone
)
160 addOption(label
,zone
,0,0,1);
163 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
165 addOption(label
,zone
,init
,min
,max
);
168 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
170 addOption(label
,zone
,init
,min
,max
);
173 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
)
175 addOption(label
,zone
,init
,min
,max
);
178 // -- passive widgets
180 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) {}
181 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) {}
182 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) {}
183 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) {}
186 virtual void openFrameBox(const char* label
) { }
187 virtual void openTabBox(const char* label
) { }
188 virtual void openHorizontalBox(const char* label
) { }
189 virtual void openVerticalBox(const char* label
) { }
191 //virtual void openFrameBox(const char* label) { openAnyBox(label); }
192 //virtual void openTabBox(const char* label) { openAnyBox(label); }
193 //virtual void openHorizontalBox(const char* label) { openAnyBox(label); }
194 //virtual void openVerticalBox(const char* label) { openAnyBox(label); }
196 //virtual void closeBox() { fPrefix.pop(); }
197 virtual void closeBox() { }
198 virtual void run() {}
199 virtual void show() {}
205 /******************************************************************************
206 *******************************************************************************
210 *******************************************************************************
211 *******************************************************************************/
215 //----------------------------------------------------------------
216 // abstract definition of a signal processor
217 //----------------------------------------------------------------
226 virtual int getNumInputs() = 0;
227 virtual int getNumOutputs() = 0;
228 virtual void buildUserInterface(UI
* interface
) = 0;
229 virtual void init(int samplingRate
) = 0;
230 virtual void compute(int len
, float** inputs
, float** outputs
) = 0;
234 //----------------------------------------------------------------------------
235 // FAUST generated signal processor
236 //----------------------------------------------------------------------------
242 //----------------------------------------------------------------------------
244 //----------------------------------------------------------------------------
246 // Prefered way to allocate memory
247 #define ALLOC(x) alloca(x)
248 #define FREE(x) ((void)0)
249 // if ALLOCA is not available use MALLOC
250 //#define ALLOC(x) malloc(x)
251 //#define FREE(x) free(x)
253 #define QUOTEME(x) #x
255 #define DEFAULT_SAMPLERATE 44100
256 #define DEFAULT_BLOCKSIZE 64
258 // linear interpolation for vector valued control inputs
260 interpolate_ctrlin (float *vals
, NDArray in
, int n
)
262 int nin
= in
.length();
263 double ratio
= (double)(n
-1)/(double)(nin
-1);
264 int irat
= (int) ratio
;
265 double frat
= ratio
- (double) irat
;
270 for (int j
=0; j
<(nin
-1); j
++) {
272 int seglength
= irat
;
278 del
= (in(j
+1) - in(j
)) / (float) seglength
;
280 for (int k
=0; k
<seglength
; k
++) {
292 DEFUN_DLD (FAUST_FUNC_NAME
, args
, nargout
,
293 "type " QUOTEME(FAUST_FUNC_NAME
) "() to see the arguments.\n")
295 int nargin
= args
.length();
299 int maxInputLength
= 0;
304 float **controlinputs
;
307 int allscalarctrls
= 1;
308 // TODO: float **controloutputs;
313 octave_value_list retval
;
316 FNUI
* interface
= new FNUI();
317 DSP
.buildUserInterface(interface
);
319 // check if global variable FAUST_BLOCKSIZE is set.
320 tmp
= get_global_value ("FAUST_BLOCKSIZE", true);
321 if (tmp
.is_defined ())
322 bsize
= (int) tmp
.scalar_value();
324 bsize
= DEFAULT_BLOCKSIZE
;
327 // check if global variable FAUST_SAMPLERATE is set.
328 tmp
= get_global_value ("FAUST_SAMPLERATE", true);
329 if (tmp
.is_defined ())
330 srate
= (int) tmp
.scalar_value();
332 srate
= DEFAULT_SAMPLERATE
;
336 opts
= interface
->getOpts();
338 numIn
= DSP
.getNumInputs();
339 numOut
= DSP
.getNumOutputs();
340 numOpts
= interface
->getNumOptions();
342 // print a usage message in case the function is called with too few arguments
343 if (nargin
< numIn
|| nargin
== 0) {
345 octave_stdout
<< "[out1";
346 for (i
=2; i
<=numOut
; i
++)
347 octave_stdout
<< ",out" << i
;
348 octave_stdout
<< "] = " << QUOTEME(FAUST_FUNC_NAME
) << "(";
350 octave_stdout
<< "out = " << QUOTEME(FAUST_FUNC_NAME
) << "(";
353 octave_stdout
<< "numsamps";
355 octave_stdout
<< "in1";
356 for (i
=2; i
<=numIn
; i
++)
357 octave_stdout
<< ", in" << i
;
358 for (i
=0; i
<numOpts
; i
++)
359 octave_stdout
<< ", " << opts
[i
].fName
;
360 octave_stdout
<< ")\n";
365 // If we have inputs we use the length of the longest input vector
366 // as length of the output to be produced.
367 // If we don't have inputs, the first argument specifies the number of
368 // samples to be produced.
370 maxInputLength
= args(0).scalar_value();
374 for (i
=0; i
<numIn
; i
++) {
375 octave_idx_type nr
= args(i
).matrix_value().rows();
376 octave_idx_type nc
= args(i
).matrix_value().columns();
378 if (nc
> maxInputLength
)
380 } else if (nc
== 1) {
381 if (nr
> maxInputLength
)
385 octave_stdout
<< "Argument " << i
<< " has wrong dimensions " << nr
<< "x" << nc
<< "\n";
391 ctrllength
= (maxInputLength
+bsize
-1)/bsize
;
393 // check for arguments that should serve as control inputs
394 for (i
=ctrlargoff
; i
<nargin
; i
++) {
395 if ((i
-ctrlargoff
) < numOpts
) {
396 NDArray v
= args(i
).array_value();
397 if (v
.length() > 1) {
399 opts
[i
-ctrlargoff
].fVals
= (float*) ALLOC(sizeof(float)*ctrllength
);
400 interpolate_ctrlin(opts
[i
-ctrlargoff
].fVals
, v
, ctrllength
);
401 *opts
[i
-ctrlargoff
].fZone
= (float) v(0);
403 *opts
[i
-ctrlargoff
].fZone
= (float) args(i
).scalar_value();
408 for (i
=0; i
<numOpts
; i
++) {
409 octave_stdout
<< "Parameter " << opts
[i
].fName
<< ": " << *opts
[i
].fZone
<< "\n";
412 finputs
= (float**) ALLOC(sizeof(float*) * numIn
);
413 foutputs
= (float**) ALLOC(sizeof(float*) * numOut
);
415 // Copy the matrix and convert to floats - This is a real slowdown!
416 for (i
=0; i
<numIn
; i
++) {
417 Matrix m
= args(i
).matrix_value();
419 finputs
[i
] = (float*) ALLOC(maxInputLength
* sizeof(float));
420 memset(finputs
[i
], 0, sizeof(float)*maxInputLength
);
422 if (m
.rows() > m
.columns()) {
423 for (int j
=0; j
<m
.rows(); j
++) {
424 *p
++ = (float) m(j
,0);
427 for (int j
=0; j
<m
.columns(); j
++) {
428 *p
++ = (float) m(0,j
);
433 // allocate output vectors
434 for (i
=0; i
<numOut
; i
++) {
435 foutputs
[i
] = (float*) ALLOC(maxInputLength
* sizeof(float));
436 memset(foutputs
[i
], 0, sizeof(float)*maxInputLength
);
439 if (allscalarctrls
) {
440 DSP
.compute(maxInputLength
, finputs
, foutputs
);
442 int nleft
= maxInputLength
;
446 fins
= (float**) ALLOC(sizeof(float*) * numIn
);
447 fouts
= (float**) ALLOC(sizeof(float*) * numOut
);
448 memcpy(fins
, finputs
, sizeof(float*)*numIn
);
449 memcpy(fouts
, foutputs
, sizeof(float*)*numOut
);
451 int n
= min(bsize
, nleft
);
452 for (i
=0; i
<numOpts
; i
++) {
454 *opts
[i
].fZone
= opts
[i
].fVals
[k
];
457 DSP
.compute(n
, fins
, fouts
);
460 for (i
=0; i
<numIn
; i
++)
462 for (i
=0; i
<numOut
; i
++)
469 // copy the output from the float arrays (and free all tmp memory if malloc is used)
470 for (i
=0; i
<numOut
; i
++) {
471 Matrix output
= Matrix(1, maxInputLength
);
472 for (int j
=0; j
<maxInputLength
; j
++)
473 output(0, j
) = (double) foutputs
[i
][j
];
477 for (i
=0; i
<numOpts
; i
++) {
482 for (i
=0; i
<numIn
; i
++) {