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) 2004-2011 Remy Muller
15 ----------------------------BSD License------------------------------
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
20 * Redistributions of source code must retain the above copyright
21 notice, this list of conditions and the following disclaimer.
22 * Redistributions in binary form must reproduce the above
23 copyright notice, this list of conditions and the following
24 disclaimer in the documentation and/or other materials provided
25 with the distribution.
26 * Neither the name of Remy Muller nor the names of its
27 contributors may be used to endorse or promote products derived
28 from this software without specific prior written permission.
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41 OF THE POSSIBILITY OF SUCH DAMAGE.
43 ----------------------------VST SDK----------------------------------
44 In order to compile a VST (TM) plugin with this architecture file
45 you will need the proprietary VST SDK from Steinberg. Please check
46 the corresponding license.
48 ************************************************************************
49 ************************************************************************/
52 /********************************************************************
53 * VST wrapper for the FAUST language.
54 * Author: remy muller remy.muller@ircam.fr
55 * http://www.smartelectronix.com/~mdsp/
58 * Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
59 * http://www.grame.fr/
61 ********************************************************************/
80 // There is a bug with powf() when cross compiling with mingw
81 // the following macro avoid the problem
83 #define powf(x,y) pow(x,y)
84 #define expf(x) exp(x)
87 // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
88 // flags to avoid costly denormals
90 #include <xmmintrin.h>
92 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
94 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
97 #define AVOIDDENORMALS
102 void declare (const char* key
, const char* value
) { }
108 //-------------------------------------------------------------------
109 // Generic min and max using gcc extensions
110 //-------------------------------------------------------------------
112 #define max(x,y) ((x)>?(y))
113 #define min(x,y) ((x)<?(y))
115 //abs(x) should be already predefined
119 //-------------------------------------------------------------------
120 // Generic min and max using c++ inline
121 //-------------------------------------------------------------------
123 inline int max (unsigned int a
, unsigned int b
) { return (a
>b
) ? a
: b
; }
124 inline int max (int a
, int b
) { return (a
>b
) ? a
: b
; }
126 inline long max (long a
, long b
) { return (a
>b
) ? a
: b
; }
127 inline long max (int a
, long b
) { return (a
>b
) ? a
: b
; }
128 inline long max (long a
, int b
) { return (a
>b
) ? a
: b
; }
130 inline float max (float a
, float b
) { return (a
>b
) ? a
: b
; }
131 inline float max (int a
, float b
) { return (a
>b
) ? a
: b
; }
132 inline float max (float a
, int b
) { return (a
>b
) ? a
: b
; }
133 inline float max (long a
, float b
) { return (a
>b
) ? a
: b
; }
134 inline float max (float a
, long b
) { return (a
>b
) ? a
: b
; }
136 inline double max (double a
, double b
) { return (a
>b
) ? a
: b
; }
137 inline double max (int a
, double b
) { return (a
>b
) ? a
: b
; }
138 inline double max (double a
, int b
) { return (a
>b
) ? a
: b
; }
139 inline double max (long a
, double b
) { return (a
>b
) ? a
: b
; }
140 inline double max (double a
, long b
) { return (a
>b
) ? a
: b
; }
141 inline double max (float a
, double b
) { return (a
>b
) ? a
: b
; }
142 inline double max (double a
, float b
) { return (a
>b
) ? a
: b
; }
145 inline int min (int a
, int b
) { return (a
<b
) ? a
: b
; }
147 inline long min (long a
, long b
) { return (a
<b
) ? a
: b
; }
148 inline long min (int a
, long b
) { return (a
<b
) ? a
: b
; }
149 inline long min (long a
, int b
) { return (a
<b
) ? a
: b
; }
151 inline float min (float a
, float b
) { return (a
<b
) ? a
: b
; }
152 inline float min (int a
, float b
) { return (a
<b
) ? a
: b
; }
153 inline float min (float a
, int b
) { return (a
<b
) ? a
: b
; }
154 inline float min (long a
, float b
) { return (a
<b
) ? a
: b
; }
155 inline float min (float a
, long b
) { return (a
<b
) ? a
: b
; }
157 inline double min (double a
, double b
) { return (a
<b
) ? a
: b
; }
158 inline double min (int a
, double b
) { return (a
<b
) ? a
: b
; }
159 inline double min (double a
, int b
) { return (a
<b
) ? a
: b
; }
160 inline double min (long a
, double b
) { return (a
<b
) ? a
: b
; }
161 inline double min (double a
, long b
) { return (a
<b
) ? a
: b
; }
162 inline double min (float a
, double b
) { return (a
<b
) ? a
: b
; }
163 inline double min (double a
, float b
) { return (a
<b
) ? a
: b
; }
167 // abs is now predefined
168 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
171 inline int lsr (int x
, int n
) { return int(((unsigned int)x
) >> n
); }
173 inline int int2pow2 (int x
) { int r
=0; while ((1<<r
)<x
) r
++; return r
; }
176 /******************************************************************************
177 *******************************************************************************
181 *******************************************************************************
182 *******************************************************************************/
184 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
185 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
189 /******************************************************************************
190 *******************************************************************************
194 *******************************************************************************
195 *******************************************************************************/
203 UI() : fStopped(false) {}
206 virtual void addButton(char* label
, float* zone
) = 0;
207 virtual void addToggleButton(char* label
, float* zone
) = 0;
208 virtual void addCheckButton(char* label
, float* zone
) = 0;
209 virtual void addVerticalSlider(char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
210 virtual void addHorizontalSlider(char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
211 virtual void addNumEntry(char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
213 virtual void addNumDisplay(char* label
, float* zone
, int precision
) = 0;
214 virtual void addTextDisplay(char* label
, float* zone
, char* names
[], float min
, float max
) = 0;
215 virtual void addHorizontalBargraph(char* label
, float* zone
, float min
, float max
) = 0;
216 virtual void addVerticalBargraph(char* label
, float* zone
, float min
, float max
) = 0;
218 virtual void openFrameBox(char* label
) = 0;
219 virtual void openTabBox(char* label
) = 0;
220 virtual void openHorizontalBox(char* label
) = 0;
221 virtual void openVerticalBox(char* label
) = 0;
222 virtual void closeBox() = 0;
224 virtual void run() {};
226 void stop() { fStopped
= true; }
227 bool stopped() { return fStopped
; }
229 virtual void declare(float* zone
, const char* key
, const char* value
) {}
233 /******************************************************************************
234 *******************************************************************************
238 *******************************************************************************
239 *******************************************************************************/
243 //----------------------------------------------------------------
244 // definition du processeur de signal
245 //----------------------------------------------------------------
257 virtual int getNumInputs() = 0;
258 virtual int getNumOutputs() = 0;
259 virtual void buildUserInterface(UI
* interface
) = 0;
260 virtual void init(int samplingRate
) = 0;
261 virtual void compute(int len
, float** inputs
, float** outputs
) = 0;
264 /********************END ARCHITECTURE SECTION (part 1/2)****************/
266 /**************************BEGIN USER SECTION **************************/
270 /***************************END USER SECTION ***************************/
272 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
274 /******************************************************************************
278 ******************************************************************************/
280 #include "audioeffectx.h"
284 class Faust
: public AudioEffectX
287 Faust(audioMasterCallback audioMaster
);
290 virtual void process(float **inputs
, float **outputs
, long sampleFrames
);
291 virtual void processReplacing(float **inputs
, float **outputs
, long sampleFrames
);
293 virtual void setProgramName(char *name
);
294 virtual void setProgram(long index
);
295 virtual void getProgramName(char *name
);
297 virtual void setParameter(long index
, float value
);
298 virtual float getParameter(long index
);
299 virtual void getParameterLabel(long index
, char *label
);
300 virtual void getParameterDisplay(long index
, char *text
);
301 virtual void getParameterName(long index
, char *text
);
303 virtual void setSampleRate(float sampleRate
);
305 virtual bool getEffectName (char* name
);
306 virtual bool getVendorString (char* text
);
307 virtual bool getProductString (char* text
);
309 virtual bool getInputProperties (long index
, VstPinProperties
* properties
);
310 virtual bool getOutputProperties (long index
, VstPinProperties
* properties
);
317 /*--------------------------------------------------------------------------*/
323 float range(float min
, float max
, float val
)
324 { // VST parameters are normalized in the range [0;1]
325 val
= min
+ val
* (max
- min
);
326 return (val
< min
) ? min
: (val
> max
) ? max
: val
;
330 vstUIObject(char* label
, float* zone
):fLabel(label
),fZone(zone
) {}
331 virtual ~vstUIObject() {}
333 virtual void GetName(char *text
){std::strcpy(text
,fLabel
.c_str());}
334 virtual void SetValue(double f
) {*fZone
= range(0.0f
,1.0f
,(float)f
);}
335 virtual float GetValue() {return *fZone
;}
336 virtual void GetDisplay(char *text
){std::sprintf(text
,"%f",*fZone
);}
338 { /* returns the sum of all the ASCII characters contained in the parameter's label */
341 for(i
=0,acc
= 0;i
<fLabel
.length();i
++) acc
+= (fLabel
.c_str())[i
];
346 /*--------------------------------------------------------------------------*/
347 class vstToggleButton
: public vstUIObject
{
351 vstToggleButton(char* label
, float* zone
):vstUIObject(label
,zone
) {}
352 virtual ~vstToggleButton() {}
353 virtual float GetValue() {return *fZone
;}
354 virtual void SetValue(double f
) {*fZone
= (f
>0.5f
)?1.0f
:0.0f
;}
355 virtual void GetDisplay(char *text
){(*fZone
>0.5f
)? std::strcpy(text
,"ON"): std::strcpy(text
,"OFF");}
358 /*--------------------------------------------------------------------------*/
359 class vstCheckButton
: public vstUIObject
{
363 vstCheckButton(char* label
, float* zone
):vstUIObject(label
,zone
) {}
364 virtual ~vstCheckButton() {}
365 virtual float GetValue() {return *fZone
;}
366 virtual void SetValue(double f
) {*fZone
= (f
>0.5f
)?1.0f
:0.0f
;}
367 virtual void GetDisplay(char *text
){(*fZone
>0.5f
)? std::strcpy(text
,"ON"): std::strcpy(text
,"OFF");}
370 /*--------------------------------------------------------------------------*/
371 class vstButton
: public vstUIObject
{
375 vstButton(char* label
, float* zone
):vstUIObject(label
,zone
) {}
376 virtual ~vstButton() {}
377 virtual float GetValue() {return *fZone
;}
378 virtual void SetValue(double f
) {*fZone
= (f
>0.5f
)?1.0f
:0.0f
;}
379 virtual void GetDisplay(char *text
){(*fZone
>0.5f
)? std::strcpy(text
,"ON"): std::strcpy(text
,"OFF");}
382 /*--------------------------------------------------------------------------*/
383 class vstSlider
: public vstUIObject
{
394 vstSlider(char* label
, float* zone
, float init
, float min
, float max
, float step
)
395 :vstUIObject(label
,zone
), fInit(init
), fMin(min
), fMax(max
),fStep(step
) {}
396 virtual ~vstSlider() {}
398 virtual float GetValue() {return (*fZone
-fMin
)/(fMax
-fMin
);} // normalize
399 virtual void SetValue(double f
) {*fZone
= range(fMin
,fMax
,(float)f
);} // expand
402 /*--------------------------------------------------------------------------*/
403 class vstUI
: public UI
407 vector
<vstUIObject
*> fUITable
;
414 for (vector
<vstUIObject
*>::iterator iter
= fUITable
.begin(); iter
!= fUITable
.end(); iter
++) delete *iter
;
417 void addButton(char* label
, float* zone
) {fUITable
.push_back(new vstButton(label
, zone
));}
419 void addToggleButton(char* label
, float* zone
) {fUITable
.push_back(new vstToggleButton(label
, zone
));}
421 void addCheckButton(char* label
, float* zone
) {fUITable
.push_back(new vstCheckButton(label
, zone
));}
423 void addVerticalSlider(char* label
, float* zone
, float init
, float min
, float max
, float step
)
425 fUITable
.push_back(new vstSlider(label
, zone
, init
, min
, max
, step
));
428 void addHorizontalSlider(char* label
, float* zone
, float init
, float min
, float max
, float step
)
430 fUITable
.push_back(new vstSlider(label
, zone
, init
, min
, max
, step
));
433 void addNumEntry(char* label
, float* zone
, float init
, float min
, float max
, float step
) {}
435 void openFrameBox(char* label
) {}
436 void openTabBox(char* label
) {}
437 void openHorizontalBox(char* label
) {}
438 void openVerticalBox(char* label
) {}
441 void SetValue(int index
, double f
) {assert(index
<fUITable
.size()); fUITable
[index
]->SetValue(f
);}
442 float GetValue(long index
) {assert(index
<fUITable
.size()); return fUITable
[index
]->GetValue();}
443 void GetDisplay(long index
, char *text
) {assert(index
<fUITable
.size()); fUITable
[index
]->GetDisplay(text
);}
444 void GetName(long index
, char *text
) {assert(index
<fUITable
.size()); fUITable
[index
]->GetName(text
);}
445 long GetNumParams() {return fUITable
.size();}
448 /* Creates a (unique?)id by summing all the parameter's labels,
449 * then wrapping it in the range [0;maxNumberOfId] and adding
450 * this number to the offset made by the Four Character ID: 'FAUS'
453 const long maxNumberOfId
= 128;
454 long baseid
= 'FAUS';
456 for(int i
=0;i
<fUITable
.size();i
++) id
+= fUITable
[i
]->GetID();
457 return baseid
+ id
% maxNumberOfId
;
461 void addNumDisplay(char* label
, float* zone
, int precision
){}
462 void addTextDisplay(char* label
, float* zone
, char* names
[], float min
, float max
){}
463 void addHorizontalBargraph(char* label
, float* zone
, float min
, float max
){}
464 void addVerticalBargraph(char* label
, float* zone
, float min
, float max
){}
467 //-----------------------------------------------------------------------------
468 #define NUM_PROGRAMS 0
469 #define FAKE_NUM_PARAMS 16
471 Faust::Faust(audioMasterCallback audioMaster
)
472 :AudioEffectX(audioMaster
, NUM_PROGRAMS
,FAKE_NUM_PARAMS
)
476 dsp
->buildUserInterface(dspUI
);
477 dsp
->init(long(getSampleRate()));
479 /* we override here the fake number of parameters with the real one*/
480 this->cEffect
.numParams
= this->numParams
= dspUI
->GetNumParams();
482 setNumInputs(dsp
->getNumInputs());
483 setNumOutputs(dsp
->getNumOutputs());
484 setUniqueID(dspUI
->makeID());
485 canProcessReplacing();//?
488 //----------------------------------------------------------------------------
492 if (dspUI
) delete dspUI
;
495 //-----------------------------------------------------------------------------
496 void Faust::setParameter(long index
, float value
)
499 dspUI
->SetValue(index
,value
);
501 //-----------------------------------------------------------------------------
502 float Faust::getParameter(long index
)
505 return dspUI
->GetValue(index
);
509 //-----------------------------------------------------------------------------
510 void Faust::getParameterName(long index
, char *label
)
513 dspUI
->GetName(index
,label
);
517 //-----------------------------------------------------------------------------
518 void Faust::getParameterDisplay(long index
, char *text
)
521 dspUI
->GetDisplay(index
,text
);
525 //-----------------------------------------------------------------------------
526 void Faust::getParameterLabel(long index
, char *label
)
531 //-----------------------------------------------------------------------------
532 void Faust::setProgramName(char *name
)
534 // this template does not use programs yet
536 //-----------------------------------------------------------------------------
537 void Faust::setProgram(long index
)
539 // this template does not use programs yet
541 //-----------------------------------------------------------------------------
542 void Faust::getProgramName(char *name
)
544 // this template does not use programs yet
547 //-----------------------------------------------------------------------------
548 void Faust::process(float **inputs
, float **outputs
, long sampleFrames
)
551 dsp
->compute(sampleFrames
, inputs
, outputs
);
553 //-----------------------------------------------------------------------------
554 void Faust::processReplacing(float **inputs
, float **outputs
, long sampleFrames
)
557 dsp
->compute(sampleFrames
, inputs
, outputs
);
559 //-----------------------------------------------------------------------------
560 void Faust::setSampleRate(float sampleRate
)
563 AudioEffect::setSampleRate(sampleRate
);
564 dsp
->init(long(getSampleRate()));
566 //-----------------------------------------------------------------------------------------
567 bool Faust::getEffectName (char* name
)
571 //-----------------------------------------------------------------------------------------
572 bool Faust::getVendorString (char* text
)
574 strcpy (text
, "Grame");
577 //-----------------------------------------------------------------------------------------
578 bool Faust::getProductString (char* text
)
580 strcpy (text
, "Faust DSP");
583 //-----------------------------------------------------------------------------------------
584 bool Faust::getInputProperties (long index
, VstPinProperties
* properties
)
586 if(index
>=0 && index
<dsp
->getNumOutputs())
588 sprintf (properties
->label
, "Grame Faust DSP: %d",index
);
589 sprintf (properties
->shortLabel
, "Faust: %d",index
);
590 properties
->flags
= kVstPinIsActive
;
596 //-----------------------------------------------------------------------------------------
597 bool Faust::getOutputProperties (long index
, VstPinProperties
* properties
)
599 if(index
>=0 && index
<dsp
->getNumInputs())
601 sprintf (properties
->label
, "Grame Faust DSP: %d",index
);
602 sprintf (properties
->shortLabel
, "Faust: %d",index
);
603 properties
->flags
= kVstPinIsActive
;
610 /*****************************************************************************
614 ******************************************************************************/
621 // prototype of the export function main
623 #define main main_plugin
624 extern "C" __declspec(dllexport
) AEffect
*main_plugin (audioMasterCallback audioMaster
);
627 #define main main_macho
628 extern "C" AEffect
*main_macho (audioMasterCallback audioMaster
);
631 AEffect
*main (audioMasterCallback audioMaster
);
634 AEffect
*main (audioMasterCallback audioMaster
)
637 if (!audioMaster (0, audioMasterVersion
, 0, 0, 0, 0))
638 return 0; // old version
640 AudioEffect
* effect
= new Faust(audioMaster
);
648 return effect
->getAeffect ();
658 BOOL WINAPI
DllMain (HINSTANCE hInst
, DWORD dwReason
, LPVOID lpvReserved
)
665 /********************END ARCHITECTURE SECTION (part 2/2)****************/