X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpretor/preprocessor/faust-0.9.47mr3/architecture/vsti-mono.cpp diff --git a/interpretor/preprocessor/faust-0.9.47mr3/architecture/vsti-mono.cpp b/interpretor/preprocessor/faust-0.9.47mr3/architecture/vsti-mono.cpp deleted file mode 100644 index 51fc0f9..0000000 --- a/interpretor/preprocessor/faust-0.9.47mr3/architecture/vsti-mono.cpp +++ /dev/null @@ -1,1072 +0,0 @@ -/************************************************************************ - - IMPORTANT NOTE : this file contains two clearly delimited sections : - the ARCHITECTURE section (in two parts) and the USER section. Each section - is governed by its own copyright and license. Please check individually - each section for license and copyright information. -*************************************************************************/ - -/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ - -/************************************************************************ - ************************************************************************ - FAUST Architecture File - Copyright (C) 2007-2011 Julius Smith - All rights reserved. - ----------------------------BSD License------------------------------ - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of Julius Smith nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - OF THE POSSIBILITY OF SUCH DAMAGE. - - ----------------------------VST SDK---------------------------------- - In order to compile a VST (TM) plugin with this architecture file - you will need the proprietary VST SDK from Steinberg. Please check - the corresponding license. - - ************************************************************************ - ************************************************************************/ - -/******************************************************************** - * vsti-mono.cpp - Monaural VSTi-2.4 wrapper for the FAUST language. - * - * Usage: faust -a vsti-mono.cpp myfaustprog.dsp - * - * By Julius Smith (http://ccrma.stanford.edu/~jos/), based on vst.cpp - * by remy muller - * (http://www.smartelectronix.com/~mdsp/). Essentially, vst.cpp was - * first edited to look more like the "again" programming sample that - * comes with the VST-2.4 SDK from Steinberg. Next, features from the - * "vstxsynth" program sample were added to give simple MIDI synth - * support analogous to that of faust2pd, except that only one voice - * is supported. (If the Faust patch has any input signals, this - * architecture file should reduce to vst2p4.cpp --- i.e., basic VST - * plugin support.) As with faust2pd, to obtain MIDI control via - * NoteOn/Off, Velocity, and KeyNumber, there must be a button named - * "gate" and sliders (or numeric entries) named "gain" and "freq" in - * the Faust patch specified in myfaustprog.dsp. - * - * NOTES: - * Relies on automatically generated slider GUI for VST plugins. - * - Horizontal and vertical sliders mapped to "vstSlider" - * - Numeric Entries similarly converted to "vstSlider" - * - No support for bar graphs or additional numeric and text displays - * - Tested on the Muse Receptor Pro 1.0, System Version 1.6.20070717, - * using Visual C++ 2008 Express Edition - * (part of the Microsoft Visual Studio 2008, Beta 2) - * - Reference: - * http://ccrma.stanford.edu/realsimple/faust/Generating_VST_Plugin_Faust.html - * - * FAUST - * Copyright (C) 2003-2007 GRAME, Centre National de Creation Musicale - * http://www.grame.fr/ - * - ********************************************************************/ - -// Suggestion: Faust could replace all leading comments in this file -// by the following shorter comment: - -/******************************************************************** - * C++ source generated by the following command line: - * - * faust -a vsti.cpp name.dsp -o name-vsti.cpp - * - ********************************************************************/ - -// (where the filenames could be really right, and the path to vsti.cpp -// could be included as well.) - -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include - -using namespace std ; - -// There is a bug with powf() when cross compiling with mingw -// the following macro avoid the problem -#ifdef WIN32 -#define powf(x,y) pow(x,y) -#define expf(x) exp(x) -#endif - -// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) -// flags to avoid costly denormals -#ifdef __SSE__ - #include - #ifdef __SSE2__ - #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) - #else - #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) - #endif -#else - #define AVOIDDENORMALS -#endif - -struct Meta -{ - void declare (const char* key, const char* value) { } -}; - - -#ifdef __GNUC__ - -//------------------------------------------------------------------- -// Generic min and max using gcc extensions -//------------------------------------------------------------------- - -#define max(x,y) ((x)>?(y)) -#define min(x,y) ((x)b) ? a : b; } -inline int max (int a, int b) { return (a>b) ? a : b; } - -inline long max (long a, long b) { return (a>b) ? a : b; } -inline long max (int a, long b) { return (a>b) ? a : b; } -inline long max (long a, int b) { return (a>b) ? a : b; } - -inline float max (float a, float b) { return (a>b) ? a : b; } -inline float max (int a, float b) { return (a>b) ? a : b; } -inline float max (float a, int b) { return (a>b) ? a : b; } -inline float max (long a, float b) { return (a>b) ? a : b; } -inline float max (float a, long b) { return (a>b) ? a : b; } - -inline double max (double a, double b) { return (a>b) ? a : b; } -inline double max (int a, double b) { return (a>b) ? a : b; } -inline double max (double a, int b) { return (a>b) ? a : b; } -inline double max (long a, double b) { return (a>b) ? a : b; } -inline double max (double a, long b) { return (a>b) ? a : b; } -inline double max (float a, double b) { return (a>b) ? a : b; } -inline double max (double a, float b) { return (a>b) ? a : b; } - -inline int min (int a, int b) { return (a T abs (T a) { return (a> n); } - -inline int int2pow2 (int x) { int r=0; while ((1<> - -/****************************************************************************** -******************************************************************************* -* -* USER INTERFACE -* -******************************************************************************* -*******************************************************************************/ - -class UI -{ - bool fStopped; - -public: - - UI() : fStopped(false) {} - virtual ~UI() {} - - virtual void addButton(char* label, float* zone) = 0; - virtual void addToggleButton(char* label, float* zone) = 0; - virtual void addCheckButton(char* label, float* zone) = 0; - virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0; - virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0; - virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0; - - virtual void addNumDisplay(char* label, float* zone, int precision) = 0; - virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max) = 0; - virtual void addHorizontalBargraph(char* label, float* zone, float min, float max) = 0; - virtual void addVerticalBargraph(char* label, float* zone, float min, float max) = 0; - - virtual void openFrameBox(char* label) = 0; - virtual void openTabBox(char* label) = 0; - virtual void openHorizontalBox(char* label) = 0; - virtual void openVerticalBox(char* label) = 0; - virtual void closeBox() = 0; - - virtual void run() {}; - - void stop() { fStopped = true; } - bool stopped() { return fStopped; } - - virtual void declare(float* zone, const char* key, const char* value) {} -}; - - -/****************************************************************************** -******************************************************************************* -* -* FAUST DSP -* -******************************************************************************* -*******************************************************************************/ - - - -//---------------------------------------------------------------- -// Base dsp class for this architecture -//---------------------------------------------------------------- - -class dsp { - -protected: - - int fSamplingFreq; - -public: - - dsp() {} - virtual ~dsp() {} - virtual int getNumInputs() = 0; - virtual int getNumOutputs() = 0; - virtual void buildUserInterface(UI* interface) = 0; - virtual void init(int samplingRate) = 0; - virtual void compute(int len, float** inputs, float** outputs) = 0; -}; - -/********************END ARCHITECTURE SECTION (part 1/2)****************/ - -/**************************BEGIN USER SECTION **************************/ - -<> - -/***************************END USER SECTION ***************************/ - -/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/ - -/****************************************************************************** - * - * VST wrapper - * - ******************************************************************************/ - -#include "audioeffectx.h" - -class vstUI; - -//------------------------------------------------------------------------------ -// Faust class prototype -//------------------------------------------------------------------------------ -class Faust : public AudioEffectX -{ -public: - Faust(audioMasterCallback audioMaster, mydsp* dspi, vstUI* dspUIi); - virtual ~Faust(); - - virtual void processReplacing (float **inputs, float **outputs, VstInt32 sampleFrames); - virtual VstInt32 processEvents (VstEvents* events); - - virtual void setProgram (VstInt32 program); - virtual void setProgramName (char *name); - virtual void getProgramName (char *name); - virtual bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char *text); - - virtual void setParameter (VstInt32 index, float value); - virtual float getParameter (VstInt32 index); - virtual void getParameterLabel (VstInt32 index, char *label); - virtual void getParameterDisplay (VstInt32 index, char *text); - virtual void getParameterName (VstInt32 index, char *text); - - virtual void setSampleRate (float sampleRate); - - virtual bool getInputProperties (VstInt32 index, VstPinProperties *properties); - virtual bool getOutputProperties (VstInt32 index, VstPinProperties *properties); - - virtual bool getEffectName (char *name); - virtual bool getVendorString (char *text); - virtual bool getProductString (char *text); - virtual VstInt32 getVendorVersion (); - virtual VstInt32 canDo (char *text); - - virtual VstInt32 getNumMidiInputChannels (); - virtual VstInt32 getNumMidiOutputChannels (); - - virtual VstInt32 getMidiProgramName (VstInt32 channel, MidiProgramName *midiProgramName); - virtual VstInt32 getCurrentMidiProgram (VstInt32 channel, MidiProgramName *currentProgram); - virtual VstInt32 getMidiProgramCategory (VstInt32 channel, MidiProgramCategory *category); - -private: - mydsp* dsp; - vstUI* dspUI; - - // For synths: - bool noteIsOn; - VstInt32 currentNote; - VstInt32 currentVelocity; - VstInt32 currentDelta; - - void initProcess (); - void noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta); - void noteOff (); - void fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn); - - char programName[kVstMaxProgNameLen + 1]; -}; - -/*--------------------------------------------------------------------------*/ -class vstUIObject { /* superclass of all VST UI widgets */ -protected: - string fLabel; - float* fZone; - - inline float clip(float min, float max, float val) - { - return (val < min) ? min : (val > max) ? max : val; - } - - inline float normalize(float min, float max, float val) - { // VST parameters are normalized to the range [0;1] on the host - val = min + val * (max - min); - return (val < min) ? min : (val > max) ? max : val; - } - -public: - vstUIObject(char* label, float* zone):fLabel(label),fZone(zone) {} - virtual ~vstUIObject() {} - - virtual void GetName(char *text){std::strcpy(text,fLabel.c_str());} - virtual void SetValue(double f) {*fZone = normalize(0.0f,1.0f,(float)f);} - virtual void SetValueNoNormalization(double f) {*fZone = clip(0.0f,1.0f,(float)f);} - virtual float GetValue() {return *fZone;} - virtual void GetDisplay(char *text){std::sprintf(text,"%f",*fZone);} - virtual long GetID() - { /* returns the sum of all the ASCII characters contained in the parameter's label */ - unsigned int i; - long acc; - for(i=0,acc = 0;i0.5f)?1.0f:0.0f;} - virtual void GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");} -}; - -/*--------------------------------------------------------------------------*/ -class vstCheckButton : public vstUIObject { - -public: - - vstCheckButton(char* label, float* zone):vstUIObject(label,zone) {} - virtual ~vstCheckButton() {} - virtual float GetValue() {return *fZone;} - virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;} - virtual void GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");} -}; - -/*--------------------------------------------------------------------------*/ -class vstButton : public vstUIObject { - -public: - - vstButton(char* label, float* zone):vstUIObject(label,zone) {} - virtual ~vstButton() {} - virtual float GetValue() {return *fZone;} - virtual void SetValue(double f) {*fZone = (f>0.5f)?1.0f:0.0f;} - virtual void GetDisplay(char *text){(*fZone>0.5f)? std::strcpy(text,"ON"): std::strcpy(text,"OFF");} -}; - -/*--------------------------------------------------------------------------*/ -class vstSlider : public vstUIObject{ - -private: - - float fInit; - float fMin; - float fMax; - float fStep; - -public: - - vstSlider(char* label, float* zone, float init, float min, float max, float step) - :vstUIObject(label,zone), fInit(init), fMin(min), fMax(max),fStep(step) {} - virtual ~vstSlider() {} - - // The VST host calls GetValue() and expects a result in [0,1]. - // The VST host calls SetValue(f) with f in [0,1]. We convert to real units. - // When we process MIDI controls, we call SetValueNoNormalization(f) with f in real units. - virtual float GetValue() {return (*fZone-fMin)/(fMax-fMin);} // normalize - virtual void SetValue(double f) {*fZone = normalize(fMin,fMax,(float)f);} // denormalize - virtual void SetValueNoNormalization(double f) {*fZone = clip(fMin,fMax,(float)f);} // raw -}; - -/*--------------------------------------------------------------------------*/ -class vstUI : public UI -{ -private: - - vector fUITable; - -public: - - int freqIndex; - int gainIndex; - int gateIndex; - - vstUI(){ - freqIndex = gainIndex = gateIndex = -1; - } - virtual ~vstUI() - { - for (vector::iterator iter = fUITable.begin(); iter != fUITable.end(); iter++) delete *iter; - } - - void setAny(int anyIndex, float val, char *str) { - if (anyIndex<0) { -#ifdef DEBUG - // On the Receptor, and perhaps other hosts, output to stderr is logged in a file. - fprintf(stderr,"*** Faust vsti: %sIndex = %d never set!\n",str,anyIndex); -#endif - return; - } - if (anyIndex >= fUITable.size()) { -#ifdef DEBUG - fprintf(stderr,"*** Faust vsti: %sIndex = %d too large!\n",str,anyIndex); -#endif - return; - } -#ifdef DEBUG - fprintf(stderr,"*** Faust vsti: Setting %sIndex = %d to %f\n",str,anyIndex,val); -#endif - fUITable[anyIndex]->SetValueNoNormalization(val); - } - - void setFreq(float val) { - setAny(freqIndex, val, "freq"); - } - - void setGate(float val) { - setAny(gateIndex, val, "gate"); - } - - void setGain(float val) { - setAny(gainIndex, val, "gain"); - } - - bool ckAnyMatch(char* label, char* indexName, int *index) { - if (_stricmp(label,indexName)==0) { -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: label '%s' matches '%s'\n",label,indexName); -#endif - *index = fUITable.size() - 1; - return true; - } - return false; - } - - void ckAllMatches(char* label) { - ckAnyMatch(label,"gain",&gainIndex); - ckAnyMatch(label,"gate",&gateIndex); - ckAnyMatch(label,"freq",&freqIndex); - } - - void addButton(char* label, float* zone) { - vstButton* theButton = new vstButton(label, zone); - fUITable.push_back(theButton); -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: Adding Button with label '%s'\n",label); -#endif - ckAnyMatch(label,"gate",&gateIndex); - } - - void addToggleButton(char* label, float* zone) {fUITable.push_back(new vstToggleButton(label, zone));} - - void addCheckButton(char* label, float* zone) {fUITable.push_back(new vstCheckButton(label, zone));} - - void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) - { - vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step); - fUITable.push_back(theSlider); -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: Adding VSlider (HSlider) with label '%s'\n",label); -#endif - ckAllMatches(label); - } - - void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) - { - vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step); - fUITable.push_back(theSlider); -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: Adding HSlider with label '%s'\n",label); -#endif - ckAllMatches(label); - } - - void addNumEntry(char* label, float* zone, float init, float min, float max, float step) - { /* Number entries converted to horizontal sliders */ - vstSlider* theSlider = new vstSlider(label, zone, init, min, max, step); - fUITable.push_back(theSlider); -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: Adding NumEntry (HSlider) with label '%s'\n",label); -#endif - ckAllMatches(label); - } - - void openFrameBox(char* label) {} - void openTabBox(char* label) {} - void openHorizontalBox(char* label) {} - void openVerticalBox(char* label) {} - void closeBox() {} - - void SetValue(VstInt32 index, double f) {assert(indexSetValue(f);} - float GetValue(VstInt32 index) {assert(indexGetValue();} - void GetDisplay(VstInt32 index, char *text) {assert(indexGetDisplay(text);} - void GetName(VstInt32 index, char *text) {assert(indexGetName(text);} - long GetNumParams() {return fUITable.size();} - - long makeID() - /* Creates a (unique?)id by summing all the parameter's labels, - * then wrapping it in the range [0;maxNumberOfId] and adding - * this number to the offset made by the Four Character ID: 'FAUS' - */ - { - const long maxNumberOfId = 128; - long baseid = 'FAUS'; - long id=0; - for(int i=0;iGetID(); - return baseid + id % maxNumberOfId; - } - - // To be implemented - void addNumDisplay(char* label, float* zone, int precision){} - void addTextDisplay(char* label, float* zone, char* names[], float min, float max){} - void addHorizontalBargraph(char* label, float* zone, float min, float max){} - void addVerticalBargraph(char* label, float* zone, float min, float max){} -}; - -//----------------------------------------------------------------------------- -// Class Implementations -//----------------------------------------------------------------------------- - -#define kNumPrograms 1 - -AudioEffect* createEffectInstance (audioMasterCallback audioMaster) -{ - // The dsp and its UI need to be allocated now because - // AudioEffectX wants the no. parameters available as an instance argument: - mydsp* dspi = new mydsp(); - vstUI* dspUIi = new vstUI(); - dspi->buildUserInterface(dspUIi); -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: created\n"); // look for this in the system log -#endif - return new Faust(audioMaster,dspi,dspUIi); -} - -//----------------------------------------------------------------------------- -// Faust -//----------------------------------------------------------------------------- -Faust::Faust(audioMasterCallback audioMaster, mydsp* dspi, vstUI* dspUIi) - :AudioEffectX(audioMaster, kNumPrograms,dspUIi->GetNumParams()) -{ - // Copy the pointers to dsp and dspUI instances and take them over - // (we'll also deallocate): - dsp = dspi; - dspUI = dspUIi; - -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: classInit:\n"); -#endif - - dsp->classInit((int)getSampleRate()); // Ask AudioEffect for sample-rate - - setProgram(0); - setProgramName("Default"); - - if (audioMaster) { - setNumInputs(dsp->getNumInputs()); - setNumOutputs(dsp->getNumOutputs()); - canProcessReplacing(); - if (dsp->getNumInputs() == 0) { - isSynth(); // at least let's hope so! - if (dsp->getNumOutputs() < 1) { - fprintf(stderr,"*** faust: vsti: No signal inputs or outputs, and Faust has no MIDI outputs!\n"); - } - } - setUniqueID(dspUI->makeID()); - } - initProcess(); - if (dsp->getNumInputs() == 0) { - suspend(); // Synths start out quiet - } -} - -//---------------------------------------------------------------------------- -Faust::~Faust() -{ - if (dsp) delete dsp; - if (dspUI) delete dspUI; -} - -//----------------------------------------------------------------------------- -void Faust::setProgram (VstInt32 program) -// Override this method of AudioEffect in order to set -// local instance variables corresponding to the current MIDI program. -// Here there is only one program. -{ - if (program < 0 || program >= kNumPrograms) { - fprintf(stderr,"*** Faust vsti: setting program to %d is OUT OF RANGE\n",program); - return; - } -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: setting program to %d\n",program); -#endif - curProgram = program; // curProgram defined in audioeffect.h -} - -//------------------------------------------------------------------------------ -void Faust::setProgramName (char* name) -{ - vst_strncpy (programName, name, kVstMaxProgNameLen); -} - -//----------------------------------------------------------------------------- -void Faust::getProgramName(char *name) -{ - vst_strncpy (name, programName, kVstMaxProgNameLen); -} - -//----------------------------------------------------------------------------- -void Faust::getParameterLabel(VstInt32 index, char *label) -{ - // We are not using parameter "units" display: - vst_strncpy (label, "", kVstMaxParamStrLen); // parameter units in Name -} - -//----------------------------------------------------------------------------- -void Faust::getParameterDisplay(VstInt32 index, char *text) -{ - if(indexGetDisplay(index,text); // get displayed float value as text - else - vst_strncpy (text, "IndexOutOfRange", kVstMaxParamStrLen); -} - -//----------------------------------------------------------------------------- -void Faust::getParameterName(VstInt32 index, char *label) -{ - if(indexGetName(index,label); // parameter name, including units - else - vst_strncpy (label, "IndexOutOfRange", kVstMaxParamStrLen); -} - -//----------------------------------------------------------------------------- -void Faust::setParameter(VstInt32 index, float value) -{ - if(indexSetValue(index,value); -} - -//----------------------------------------------------------------------------- -float Faust::getParameter(VstInt32 index) -{ - if(indexGetValue(index); - else - return 0.0f; -} - -//----------------------------------------------------------------------------- -bool Faust::getInputProperties (VstInt32 index, VstPinProperties* properties) -{ - if(index>=0 && indexgetNumInputs()) - { - sprintf (properties->label, "Grame Faust DSP input: %d",index); - sprintf (properties->shortLabel, "In %d",index); - properties->flags = kVstPinIsActive; - if (dsp->getNumInputs() == 2) { - properties->flags |= kVstPinIsStereo; - } - return true; - } - else - return false; -} - -//----------------------------------------------------------------------------- -bool Faust::getOutputProperties (VstInt32 index, VstPinProperties* properties) -{ - if(index>=0 && indexgetNumOutputs()) - { - sprintf (properties->label, "Grame Faust DSP output: %d",index); - sprintf (properties->shortLabel, "Out %d",index); - properties->flags = kVstPinIsActive; - if (dsp->getNumOutputs() == 2) { - properties->flags |= kVstPinIsStereo; - } - return true; - } - else - return false; -} - -//----------------------------------------------------------------------------- -bool Faust::getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text) -{ - if (index < kNumPrograms) { - vst_strncpy (text, programName, kVstMaxProgNameLen); - return true; - } - return false; -} - -//----------------------------------------------------------------------------- -bool Faust::getEffectName (char* name) -{ - // Get from Faust-supplied metadata? - vst_strncpy (name, "Effect Name goes here", kVstMaxEffectNameLen); - return true; -} - -//----------------------------------------------------------------------------- -bool Faust::getVendorString (char* text) -{ - vst_strncpy (text, "Vendor String goes here", kVstMaxVendorStrLen); - return true; -} - -//----------------------------------------------------------------------------- -bool Faust::getProductString (char* text) -{ - vst_strncpy (text, "Product String goes here", kVstMaxProductStrLen); - return true; -} - -//----------------------------------------------------------------------------- -VstInt32 Faust::getVendorVersion () -{ - return 1000; -} - -//----------------------------------------------------------------------------- -VstInt32 Faust::canDo (char* text) -{ - if (!strcmp (text, "receiveVstEvents")) - return 1; - if (!strcmp (text, "receiveVstMidiEvent")) - return 1; - if (!strcmp (text, "midiProgramNames")) - return 1; - return -1; // explicitly can't do; 0 => don't know -} - -//----------------------------------------------------------------------------- -VstInt32 Faust::getNumMidiInputChannels () -{ - return 1; // one MIDI-in channel -} - -//----------------------------------------------------------------------------- -VstInt32 Faust::getNumMidiOutputChannels () -{ - return 0; // no MIDI-outs -} - -//----------------------------------------------------------------------------- -VstInt32 Faust::getMidiProgramName (VstInt32 channel, MidiProgramName* mpn) -{ - VstInt32 prg = mpn->thisProgramIndex; - if (prg < 0 || prg > 0) return 0; - fillProgram (channel, prg, mpn); - return 1; // we have only 1 "MIDI program" -} - -//------------------------------------------------------------------------ -VstInt32 Faust::getCurrentMidiProgram (VstInt32 channel, MidiProgramName* mpn) -{ - // There is only one MIDI program here, so return it regardless of MIDI channel: - if (channel < 0 || channel >= 16 || !mpn) return -1; - VstInt32 prg = 0; - mpn->thisProgramIndex = prg; - fillProgram (channel, prg, mpn); - return prg; -} - -//------------------------------------------------------------------------ -void Faust::fillProgram (VstInt32 channel, VstInt32 prg, MidiProgramName* mpn) -// Fill mpn struct for given channel. Here there should be only one. -{ - mpn->midiBankMsb = mpn->midiBankLsb = -1; - mpn->reserved = 0; - mpn->flags = 0; - vst_strncpy (mpn->name, programName, kVstMaxProgNameLen); - mpn->midiProgram = (char)prg; // prg should only be 0 - mpn->parentCategoryIndex = -1; -} - -//------------------------------------------------------------------------ -VstInt32 Faust::getMidiProgramCategory (VstInt32 channel, MidiProgramCategory* cat) -// VST host wants to fill cat struct for given channel. We have only one category. -{ - cat->parentCategoryIndex = -1; // -1:no parent category - cat->flags = 0; // reserved, none defined yet, zero. - VstInt32 category = cat->thisCategoryIndex; - vst_strncpy (cat->name, "Faust Patch", kVstMaxProgNameLen); - return 1; // one category -} - -//*********************************************************************** - -//----------------------------------------------------------------------------- -void Faust::setSampleRate(float sampleRate) -{ - AudioEffect::setSampleRate(sampleRate); - dsp->instanceInit((int)getSampleRate()); // in case AudioEffect altered it -} - -//----------------------------------------------------------------------------- -void Faust::initProcess () -{ - noteIsOn = false; - currentDelta = currentNote = currentDelta = 0; - dsp->instanceInit((int)getSampleRate()); -} - -//----------------------------------------------------------------------------- -void Faust::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) -{ - AVOIDDENORMALS; -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: processReplacing . . .\n"); -#endif - - if (dsp->getNumInputs() > 0) { // We're an effect . . . keep going: - - dsp->compute(sampleFrames, inputs, outputs); - - } else { // We're a synth . . . - int i, nouts = dsp->getNumOutputs(); - - if (noteIsOn) { // we're synthesizing . . . - - if (currentDelta > 0) { // but waiting out a timestamp delay . . . - if (currentDelta >= sampleFrames) { // start time is after this chunk - currentDelta -= sampleFrames; - // According to the VST programming sample, we DON'T clear the output buffers yet. - // Could this be a bug in the sample program? I would like to add the following: - // for (i=0; icompute(sampleFrames, inputs, outptr); - free(outptr); - } - } else { - dsp->compute(sampleFrames, inputs, outputs); - } - - } else { // silence until NoteOn . . . - for (i=0; inumEvents > 0) { -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: processEvents processing %d events\n", - ev->numEvents); -#endif - } - - for (VstInt32 i = 0; i < ev->numEvents; i++) - { -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: event type = %d\n", - (ev->events[i])->type); -#endif - if ((ev->events[i])->type != kVstMidiType) { -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: EVENT IGNORED!\n"); -#endif - continue; - } - VstMidiEvent* event = (VstMidiEvent*)ev->events[i]; - char* midiData = event->midiData; - VstInt32 chan = midiData[0] & 0xf; - VstInt32 status = midiData[0] & 0xf0; -#ifdef DEBUG - fprintf(stderr,"\n=== Faust vsti: event->midiData[0] = 0x%x\n", - event->midiData[0]); - fprintf(stderr,"=== Faust vsti: midi channel = 0x%x\n", chan); - fprintf(stderr,"=== Faust vsti: midi status = 0x%x\n", status); - fprintf(stderr,"=== Faust vsti: event->midiData[1] = 0x%x\n", - event->midiData[1]); - fprintf(stderr,"=== Faust vsti: event->midiData[2] = 0x%x\n", - event->midiData[2]); -#endif - - if (status == 0x90) { // note on - VstInt32 note = midiData[1] & 0x7f; - VstInt32 velocity = midiData[2] & 0x7f; -#ifdef DEBUG - fprintf(stderr, - "=== Faust vsti: note = %d, velocity = %d, delay = %d\n", - note,velocity,event->deltaFrames); -#endif - if (velocity>0) { - noteOn(note, velocity, event->deltaFrames); - } else { - noteOff(); - } - } else if (status == 0x80) { // note off - noteOff(); - // } else if (status == 0xA0) { // poly aftertouch - } else if (status == 0xB0) { // control change - /* DO SOMETHING WITH THE CONTROLLER DATA */ - fprintf(stderr,"=== Faust vsti: CONTROL CHANGE (status 0xB0)!\n"); - if (midiData[1] == 0x7e || midiData[1] == 0x7b) { // all notes off - fprintf(stderr,"=== Faust vsti: ALL NOTES OFF!\n"); - noteOff (); // why is all-notes-off inside a "control change" event? - } - // } else if (status == 0xC0) { // program change - // } else if (status == 0xD0) { // mono aftertouch - // } else if (status == 0xE0) { // pitch change - // } else if (status == 0xF0) { // SYSX ... - } - // For a list, see - // http://www.alfred-j-faust.de/rft/midi%20status%20types.html - -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: Going to next event\n", event->midiData[2]); -#endif - - event++; - } - return 1; -} - -//----------------------------------------------------------------------------- -void Faust::noteOn (VstInt32 note, VstInt32 velocity, VstInt32 delta) -{ -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: noteOn: note = %d, vel = %d, del = %d\n",note,velocity,delta); -#endif - currentNote = note; - currentVelocity = velocity; - currentDelta = delta; - noteIsOn = true; - float freq = 440.0f * powf(2.0f,(((float)note)-69.0f)/12.0f); - float gain = velocity/127.0f; - dspUI->setFreq(freq); // Hz - requires Faust control-signal "freq" - dspUI->setGain(gain); // 0-1 - requires Faust control-signal "gain" - dspUI->setGate(1.0f); // 0 or 1 - requires Faust button-signal "gate" -} - -//----------------------------------------------------------------------------- -void Faust::noteOff () -{ - if (noteIsOn) { -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: noteOff\n"); -#endif - dspUI->setGate(0); - } else { -#ifdef DEBUG - fprintf(stderr,"=== Faust vsti: noteOff IGNORED (note was not on)\n"); -#endif - } -} - - -/********************END ARCHITECTURE SECTION (part 2/2)****************/ -