diff options
Diffstat (limited to 'externals/grill/vst/src')
-rw-r--r-- | externals/grill/vst/src/editor.cpp | 27 | ||||
-rw-r--r-- | externals/grill/vst/src/editor.h (renamed from externals/grill/vst/src/Editor.h) | 50 | ||||
-rw-r--r-- | externals/grill/vst/src/editormac.hpp (renamed from externals/grill/vst/src/EditorMac.cpp) | 0 | ||||
-rw-r--r-- | externals/grill/vst/src/editorwin.hpp (renamed from externals/grill/vst/src/EditorWin.cpp) | 13 | ||||
-rw-r--r-- | externals/grill/vst/src/vsthost.cpp (renamed from externals/grill/vst/src/VstHost.cpp) | 1606 | ||||
-rw-r--r-- | externals/grill/vst/src/vsthost.h (renamed from externals/grill/vst/src/VstHost.h) | 383 |
6 files changed, 1049 insertions, 1030 deletions
diff --git a/externals/grill/vst/src/editor.cpp b/externals/grill/vst/src/editor.cpp new file mode 100644 index 00000000..bbd91991 --- /dev/null +++ b/externals/grill/vst/src/editor.cpp @@ -0,0 +1,27 @@ +/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "editor.h"
+#include "vsthost.h"
+#include <flext.h>
+
+#if FLEXT_OS == FLEXT_OS_WIN
+// only Windows code is situated in this file
+
+#include "editorwin.hpp"
+
+#elif FLEXT_OS == FLEXT_OS_MAC
+
+#include "editormac.hpp"
+
+#else
+
+#error Platform not supported
+
+#endif
diff --git a/externals/grill/vst/src/Editor.h b/externals/grill/vst/src/editor.h index ad03f59c..480fa35b 100644 --- a/externals/grill/vst/src/Editor.h +++ b/externals/grill/vst/src/editor.h @@ -1,25 +1,25 @@ -/* -vst~ - VST plugin object for PD -based on the work of Jarno Seppänen and Mark Williamson - -Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net) -For information on usage and redistribution, and for a DISCLAIMER OF ALL -WARRANTIES, see the file, "license.txt," in this distribution. -*/ - -#ifndef __EDITOR_H -#define __EDITOR_H - -class VSTPlugin; - -void SetupEditor(); -void StartEditor(VSTPlugin *p); -void StopEditor(VSTPlugin *p); -void ShowEditor(VSTPlugin *p,bool show); -void MoveEditor(VSTPlugin *p,int x,int y); -void SizeEditor(VSTPlugin *p,int x,int y); -void TitleEditor(VSTPlugin *p,const char *t); -void CaptionEditor(VSTPlugin *p,bool c); -bool IsEditorShown(const VSTPlugin *p); - -#endif // __EDITOR_H +/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#ifndef __EDITOR_H
+#define __EDITOR_H
+
+class VSTPlugin;
+
+void SetupEditor();
+void StartEditor(VSTPlugin *p);
+void StopEditor(VSTPlugin *p);
+void ShowEditor(VSTPlugin *p,bool show);
+void MoveEditor(VSTPlugin *p,int x,int y);
+void SizeEditor(VSTPlugin *p,int x,int y);
+void TitleEditor(VSTPlugin *p,const char *t);
+void CaptionEditor(VSTPlugin *p,bool c);
+bool IsEditorShown(const VSTPlugin *p);
+
+#endif // __EDITOR_H
diff --git a/externals/grill/vst/src/EditorMac.cpp b/externals/grill/vst/src/editormac.hpp index f5316105..f5316105 100644 --- a/externals/grill/vst/src/EditorMac.cpp +++ b/externals/grill/vst/src/editormac.hpp diff --git a/externals/grill/vst/src/EditorWin.cpp b/externals/grill/vst/src/editorwin.hpp index a5601d09..f29313d4 100644 --- a/externals/grill/vst/src/EditorWin.cpp +++ b/externals/grill/vst/src/editorwin.hpp @@ -7,15 +7,12 @@ For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ -#include "Editor.h" -#include "VstHost.h" -#include <flext.h> - -#include <map> - -#if FLEXT_OS == FLEXT_OS_WIN +#if FLEXT_OS != FLEXT_OS_WIN // only Windows code is situated in this file +#error Wrong implementation +#endif +#include <map> #include <windows.h> typedef std::map<flext::thrid_t,VSTPlugin *> WndMap; @@ -292,5 +289,3 @@ bool IsEditorShown(const VSTPlugin *p) { return IsWindowVisible(p->EditorHandle()) != FALSE; } - -#endif // FLEXT_OS_WIN diff --git a/externals/grill/vst/src/VstHost.cpp b/externals/grill/vst/src/vsthost.cpp index e5d50219..7b4f3788 100644 --- a/externals/grill/vst/src/VstHost.cpp +++ b/externals/grill/vst/src/vsthost.cpp @@ -1,803 +1,803 @@ -/* -vst~ - VST plugin object for PD -based on the work of Jarno Seppänen and Mark Williamson - -Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net) -For information on usage and redistribution, and for a DISCLAIMER OF ALL -WARRANTIES, see the file, "license.txt," in this distribution. -*/ - -#include "Editor.h" -#include "VstHost.h" -#include "AEffectx.h" - -#include <ctype.h> - -typedef AEffect *(VSTCALLBACK *PVSTMAIN)(audioMasterCallback audioMaster); - - -VSTPlugin::VSTPlugin(): - h_dll(NULL),hwnd(NULL),_pEffect(NULL), - posx(0),posy(0),caption(true), - _midichannel(0),queue_size(0), - paramnamecnt(0) -{} - -VSTPlugin::~VSTPlugin() -{ - Free(); // Call free -} - -static void FreeVST(void *handle) -{ -#if FLEXT_OS == FLEXT_OS_WIN - FreeLibrary(h_dll); -#elif FLEXT_OS == FLEXT_OS_MAC -#else -#error Platform not supported -#endif -} - -#if FLEXT_OS == FLEXT_OS_MAC -OSStatus FSPathMakeFSSpec( - const UInt8 *path, - FSSpec *spec, - Boolean *isDirectory) /* can be NULL */ -{ - OSStatus result; - FSRef ref; - - /* check parameters */ - require_action(NULL != spec, BadParameter, result = paramErr); - - /* convert the POSIX path to an FSRef */ - result = FSPathMakeRef(path, &ref, isDirectory); - require_noerr(result, FSPathMakeRef); - - /* and then convert the FSRef to an FSSpec */ - result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL); - require_noerr(result, FSGetCatalogInfo); - -FSGetCatalogInfo: -FSPathMakeRef: -BadParameter: - - return ( result ); -} -#endif - -int VSTPlugin::Instance(const char *dllname) -{ -#ifdef FLEXT_DEBUG - flext::post("New Plugin 1 - %x",this); -#endif - - PVSTMAIN pluginmain; -#if FLEXT_OS == FLEXT_OS_WIN - h_dll = LoadLibrary(dllname); - if(!h_dll) - return VSTINSTANCE_ERR_NO_VALID_FILE; - - pluginmain = (PVSTMAIN)GetProcAddress(h_dll,"main"); - void *audioMasterFPtr = Master; - -#elif FLEXT_OS == FLEXT_OS_MAC - short resFileID; - FSSpec spec; - OSErr err; - - err = FSPathMakeFSSpec(dllname,&spec,NULL); - resFileID = FSpOpenResFile(&spec, fsRdPerm); - short cResCB = Count1Resources('aEff'); - - for(int i = 0; i < cResCB; i++) { - Handle codeH; - CFragConnectionID connID; - Ptr mainAddr; - Str255 errName; - Str255 fragName; - char fragNameCStr[256]; - short resID; - OSType resType; - - codeH = Get1IndResource('aEff', short(i+1)); - if (!codeH) continue; - - GetResInfo(codeH, &resID, &resType, fragName); - DetachResource(codeH); - HLock(codeH); - - err = GetMemFragment(*codeH, - GetHandleSize(codeH), - fragName, - kPrivateCFragCopy, - &connID, (Ptr *) & mainAddr, errName); - - if (!err) { - #ifdef __CFM__ - pluginmain = (PVSTMAIN)NewMachOFromCFM(mainAddr); - #else - pluginmain = (PVSTMAIN)mainAddr; - #endif - } - } - - CloseResFile(resFileID); - - void *audioMasterFPtr = -#ifdef __CFM__ - NewCFMFromMachO(Master); -#else - Master; -#endif - -#else -#error Platform not supported -#endif - - if(!pluginmain) { - FreeVST(h_dll); - _pEffect = NULL; - return VSTINSTANCE_ERR_NO_VST_PLUGIN; - } - - //This calls the "main" function and receives the pointer to the AEffect structure. - _pEffect = pluginmain((audioMasterCallback)audioMasterFPtr); - -#ifdef __MACOSX__ -#ifdef __CFM__ - DisposeCFMFromMachO(audioMasterFPtr); - DisposeMachOFromCFM(pluginmain); -#endif -#endif - - - if(!_pEffect || _pEffect->magic != kEffectMagic) { - post("VST plugin : Unable to create effect"); - - _pEffect = NULL; - FreeVST(h_dll); - h_dll = NULL; - return VSTINSTANCE_ERR_REJECTED; - } - - //init plugin - _pEffect->user = this; - - long ret = Dispatch( effOpen ); - FLEXT_ASSERT(!ret); - - ret = Dispatch( effIdentify); - FLEXT_ASSERT(ret == 'NvEf'); - - *_sProductName = 0; - ret = Dispatch( effGetProductString, 0, 0, _sProductName, 0.0f); - if(!*_sProductName) { - // no product name given by plugin -> extract it from the filename - - std::string str1(dllname); - std::string::size_type slpos = str1.rfind('\\'); - if(slpos == std::string::npos) { - slpos = str1.rfind('/'); - if(slpos == std::string::npos) - slpos = 0; - else - ++slpos; - } - else - ++slpos; - std::string str2 = str1.substr(slpos); - int snip = str2.find('.'); - if( snip != std::string::npos ) - str1 = str2.substr(0,snip); - else - str1 = str2; - strcpy(_sProductName,str1.c_str()); - } - - if(*_sProductName) { - char tmp[512]; - sprintf(tmp,"vst~ - %s",_sProductName); - title = tmp; - } - else - title = "vst~"; - - *_sVendorName = 0; - Dispatch( effGetVendorString, 0, 0,_sVendorName, 0.0f); - - _sDllName = dllname; - -#ifdef FLEXT_DEBUG - flext::post("New Plugin 2 - %x",this); -#endif - - return VSTINSTANCE_NO_ERROR; -} - - -/* -void VSTPlugin::Create(VSTPlugin *plug) -{ - h_dll = plug->h_dll; - _pEffect = plug->_pEffect; - _pEffect->user = this; - - Dispatch( effMainsChanged, 0, 1); -// strcpy(_editName,plug->_editName); On current implementation, this replaces the right one. - strcpy(_sProductName,plug->_sProductName); - strcpy(_sVendorName,plug->_sVendorName); - - _sDllName = new char[strlen(plug->_sDllName)+1]; - strcpy(_sDllName,plug->_sDllName); - - _isSynth=plug->_isSynth; - _version=plug->_version; - - plug->instantiated=false; // We are "stoling" the plugin from the "plug" object so this - // is just a "trick" so that when destructing the "plug", it - // doesn't unload the Dll. - instantiated=true; -} -*/ - -void VSTPlugin::Free() // Called also in destruction -{ - if(Is()) { - if(IsEdited()) StopEditor(this); - - // shut down plugin - Dispatch(effMainsChanged, 0, 0); - Dispatch(effClose); - -#ifdef FLEXT_DEBUG - flext::post("Free Plugin 1 - %x",this); -#endif - - _pEffect = NULL; - - // \TODO - // Here, we really have to wait until the editor thread has terminated - // otherwise WM_DESTROY etc. messages may still be pending - // in other words: this is a design flaw - // There should be a data stub accessible from the plugin object and the thread - // holding the necessary data, so that both can operate independently - - if(h_dll) { - FreeVST(h_dll); - h_dll = NULL; - } - -#ifdef FLEXT_DEBUG - flext::post("Free Plugin 2 - %x",this); -#endif - } -} - -void VSTPlugin::DspInit(float samplerate,int blocksize) -{ - // sample rate and block size must _first_ be set - Dispatch(effSetSampleRate, 0, 0,NULL,samplerate); - Dispatch(effSetBlockSize, 0, blocksize); - // than signal that mains have changed! - Dispatch(effMainsChanged, 0, 1); -} - -static void striptrail(char *txt) -{ - // strip trailing whitespace - for(int i = strlen(txt)-1; i >= 0; --i) - // cast to unsigned char since isspace functions don't want characters like 0x80 = -128 - if(isspace(((unsigned char *)txt)[i])) txt[i] = 0; -} - -void VSTPlugin::GetParamName(int numparam,char *name) const -{ - if(numparam < GetNumParams()) { - name[0] = 0; - Dispatch(effGetParamName,numparam,0,name,0.0f); - striptrail(name); - } - else - name[0] = 0; -} - -bool VSTPlugin::SetParamFloat(int parameter,float value) -{ - if(Is() && parameter >= 0 && parameter < GetNumParams()) { - _pEffect->setParameter(_pEffect,parameter,value); - return true; - } - else - return false; -} - -void VSTPlugin::GetParamValue(int numparam,char *parval) const -{ - if(Is()) { - if(numparam < GetNumParams()) { - // how many chars needed? - char par_display[64]; par_display[0] = 0; - Dispatch(effGetParamDisplay,numparam,0,par_display,0.0f); -// if(par_display[7]) par_display[8] = 0; // set trailing zero - - // how many chars needed? - char par_label[64]; par_label[0] = 0; - Dispatch(effGetParamLabel,numparam,0,par_label,0.0f); - striptrail(par_label); -// if(par_label[7]) par_label[8] = 0; // set trailing zero - - sprintf(parval,"%s%s",par_display,par_label); - } - else - strcpy(parval,"Index out of range"); - } - else - strcpy(parval,"Plugin not loaded"); -} - -float VSTPlugin::GetParamValue(int numparam) const -{ - if(Is() && numparam < GetNumParams()) - return _pEffect->getParameter(_pEffect, numparam); - else - return -1.0; -} - -void VSTPlugin::ScanParams(int cnt) -{ - if(cnt < 0) cnt = GetNumParams(); - if(paramnamecnt >= cnt) return; - if(cnt >= GetNumParams()) cnt = GetNumParams(); - - char name[64]; - for(int i = paramnamecnt; i < cnt; ++i) { - GetParamName(i,name); - if(*name) paramnames[std::string(name)] = i; - } - paramnamecnt = cnt; -} - -int VSTPlugin::GetParamIx(const char *p) const -{ - NameMap::const_iterator it = paramnames.find(std::string(p)); - return it == paramnames.end()?-1:it->second; -} - -void VSTPlugin::Edit(bool open) -{ - if(Is()) { - if(open) { - if(HasEditor() && !IsEdited()) - StartEditor(this); - } - else if(IsEdited()) - StopEditor(this); - } -} - -void VSTPlugin::StartEditing(WHandle h) -{ - FLEXT_ASSERT(h != NULL); - Dispatch(effEditOpen,0,0,hwnd = h); -// Dispatch(effEditTop); - - TitleEditor(this,title.c_str()); -} - -void VSTPlugin::StopEditing() -{ - if(Is()) { - Dispatch(effEditClose); - hwnd = NULL; - } -} - -void VSTPlugin::Visible(bool vis) -{ - if(Is() && IsEdited()) ShowEditor(this,vis); -} - -bool VSTPlugin::IsVisible() const -{ - return Is() && IsEdited() && IsEditorShown(this); -} - -bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2) -{ - if(Is()) { - VstMidiEvent* pevent = &midievent[queue_size]; - - pevent->type = kVstMidiType; - pevent->byteSize = 24; - pevent->deltaFrames = 0; - pevent->flags = 0; - pevent->detune = 0; - pevent->noteLength = 0; - pevent->noteOffset = 0; - pevent->reserved1 = 0; - pevent->reserved2 = 0; - pevent->noteOffVelocity = 0; - pevent->midiData[0] = data0; - pevent->midiData[1] = data1; - pevent->midiData[2] = data2; - pevent->midiData[3] = 0; - - if ( queue_size < MAX_EVENTS ) queue_size++; - SendMidi(); - return true; - } - else return false; -} - - -void VSTPlugin::SendMidi() -{ - if(Is() && queue_size > 0) { - // Prepare MIDI events and free queue dispatching all events - events.numEvents = queue_size; - events.reserved = 0; - for(int q = 0; q < queue_size; q++) - events.events[q] = (VstEvent*)&midievent[q]; - - Dispatch(effProcessEvents, 0, 0, &events, 0.0f); - queue_size = 0; - } -} - -static int range(int value,int mn = 0,int mx = 127) -{ - return value < mn?mn:(value > mx?mx:value); -} - -bool VSTPlugin::AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel) -{ - return AddMIDI((char)MIDI_NOTEON | midichannel,note,speed); -} - -bool VSTPlugin::AddNoteOff( unsigned char note,unsigned char midichannel) -{ - return AddMIDI((char)MIDI_NOTEOFF | midichannel,note,0); -} - -void VSTPlugin::AddAftertouch(int value) -{ - AddMIDI( (char)MIDI_NOTEOFF | _midichannel , range(value) ); -} - -void VSTPlugin::AddPitchBend(int value) -{ - AddMIDI( MIDI_PITCHBEND + (_midichannel & 0xf) , ((value>>7) & 127), (value & 127)); -} - -void VSTPlugin::AddProgramChange(int value) -{ - AddMIDI( MIDI_PROGRAMCHANGE + (_midichannel & 0xf), range(value), 0); -} - -void VSTPlugin::AddControlChange(int control, int value) -{ - AddMIDI( MIDI_CONTROLCHANGE + (_midichannel & 0xf), range(control), range(value)); -} - - -bool VSTPlugin::GetProgramName( int cat , int p, char *buf) const -{ - buf[0] = 0; - int parameter = p; - if(parameter < GetNumPrograms() && cat < GetNumCategories()) { - Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f); - striptrail(buf); - return true; - } - else - return false; -} - -void VSTPlugin::SetPos(int x,int y,bool upd) -{ - if(Is()) { - posx = x; posy = y; - if(upd && IsEdited()) MoveEditor(this,posx,posy); - } -} - -void VSTPlugin::SetCaption(bool c) -{ - if(Is()) { - caption = c; - if(IsEdited()) CaptionEditor(this,c); - } -} - -void VSTPlugin::SetTitle(const char *t) -{ - if(Is()) { - title = t; - if(IsEdited()) TitleEditor(this,t); - } -} - -void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes ) -{ - _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes ); -} - -void VSTPlugin::process( float **inputs, float **outputs, long sampleframes ) -{ - _pEffect->process( _pEffect , inputs , outputs , sampleframes ); -} - -#if 1 - -// Host callback dispatcher -long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt) -{ -#if 0 - audioMasterEnum op = (audioMasterEnum)opcode; - audioMasterEnumx opx = (audioMasterEnumx)opcode; -#endif - -#ifdef FLEXT_DEBUG -// post("VST -> host: Eff = 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt); -#endif - - switch (opcode) { - case audioMasterAutomate: // 0 -#ifdef FLEXT_DEBUG - post("Automate index=%li value=%li opt=%f",index,value,opt); -#endif - // index, value given - //! \todo set effect parameter - return 0; - case audioMasterVersion: // 1 - // support VST 2.3 -// return 2300; - return 2; - case audioMasterCurrentId: // 2 - return 0; - case audioMasterIdle: // 3 - effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); - return 0; - case audioMasterPinConnected: // 4 - //! \todo set connection state correctly (if possible..) - // index=pin, value=0..input, else..output -#ifdef FLEXT_DEBUG - post("Pin connected pin=%li conn=%li",index,value); -#endif - return 0; // 0 means connected - case audioMasterWantMidi: // 6 -#ifdef FLEXT_DEBUG - post("Want MIDI = %li",value); -#endif - return 0; // VST header says: "currently ignored" - case audioMasterGetTime: // 7 - return 0; // not supported - case audioMasterProcessEvents: { // 8 - // VST event data from plugin - VstEvent *ev = static_cast<VstEvent *>(ptr); - if(ev->type == kVstMidiType) { - VstMidiEvent *mev = static_cast<VstMidiEvent *>(ptr); -#ifdef FLEXT_DEBUG - if(mev->byteSize == 24) - post("MIDI event delta=%li len=%li offs=%li detune=%i offvel=%i",mev->deltaFrames,mev->noteLength,mev->noteOffset,(int)mev->detune,(int)mev->noteOffVelocity); - else - // has incorrect size - post("MIDI event"); -#endif - } - else { -#ifdef FLEXT_DEBUG - post("VST event type=%li",ev->type); -#endif - } - return 1; - } - case audioMasterSetTime: { // 9 - VstTimeInfo *tminfo = static_cast<VstTimeInfo *>(ptr); -#ifdef FLEXT_DEBUG - post("TimeInfo pos=%lf rate=%lf filter=%li",tminfo->samplePos,tminfo->sampleRate,value); -#endif - return 0; // not supported - } - case audioMasterTempoAt: // 10 - return 0; // not supported - case audioMasterGetNumAutomatableParameters: // 11 - return 0; // not supported - case audioMasterSizeWindow: // 15 - return 0; -// case audioMasterGetSampleRate: // 16 -// case audioMasterGetBlockSize: // 17 - case audioMasterGetCurrentProcessLevel: // 23 - // return thread state - return flext::GetThreadId() == flext::GetSysThreadId()?2:1; - case audioMasterGetVendorString: // 32 - strcpy((char*)ptr,"grrrr.org"); - return 0; - case audioMasterGetProductString: // 33 - strcpy((char *)ptr,"vst~ host external"); - return 0; - case audioMasterGetVendorVersion: // 34 - return 100; - case audioMasterCanDo: // 37 -#ifdef FLEXT_DEBUG - post("\taudioMasterCanDo PTR = %s",ptr); -#endif - if(!strcmp((char *)ptr,"sendVstEvents")) - return 1; - else if(!strcmp((char *)ptr,"sendVstMidiEvent")) - return 1; - else if(!strcmp((char *)ptr,"sendVstTimeInfo")) - return 1; // NOT YET - else if(!strcmp((char *)ptr,"receiveVstEvents")) - return 1; - else if(!strcmp((char *)ptr,"receiveVstMidiEvent")) - return 1; - else if(!strcmp((char *)ptr,"receiveVstTimeInfo")) - return 1; // NOT YET - else if(!strcmp((char *)ptr,"reportConnectionChanges")) - return 0; // \TODO PD has hard times supporting that... - else if(!strcmp((char *)ptr,"acceptIOChanges")) - return 0; // \TODO what does this means exactly? - else if(!strcmp((char *)ptr,"supplyIdle")) - return 1; - else if(!strcmp((char *)ptr,"sizeWindow")) - return 1; - else if(!strcmp((char *)ptr,"supportShell")) - return 0; // NOT YET! - else if(!strcmp((char *)ptr,"offline")) - return 0; // not supported - else if(!strcmp((char *)ptr,"asyncProcessing")) - return 0; // not supported - - return 0; // not supported - case audioMasterGetLanguage: // 38 - return kVstLangEnglish; - case audioMasterGetDirectory: // 41 - // return full path of plugin - return 0; // not supported - case audioMasterUpdateDisplay: // 42 -#ifdef FLEXT_DEBUG - post("UPDATE DISPLAY"); -#endif - return 0; - default: -#ifdef FLEXT_DEBUG - post("Unknown opcode %li",opcode); -#endif - return 0; - } -} - -#else - -// Host callback dispatcher -long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt) -{ - VSTPlugin *th = effect?(VSTPlugin *)effect->user:NULL; - if(!th) FLEXT_LOG("No this"); - -#ifdef FLEXT_DEBUG - if(opcode != audioMasterGetTime) - post("VST plugin call to host dispatcher: Eff: 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt); - //st( "audioMasterWantMidi %d " , audioMasterWantMidi); -#endif - - // Support opcodes - switch(opcode) - { - case audioMasterAutomate: - return 0; // index, value, returns 0 - - case audioMasterVersion: - return 2; // vst version, currently 7 (0 for older) - - case audioMasterCurrentId: - return 'AASH'; // returns the unique id of a plug that's currently loading - - case audioMasterIdle: - effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); - return 0; // call application idle routine (this will call effEditIdle for all open editors too) - - case audioMasterPinConnected: - if(value == 0) - return index < 2?0:1; //input - else - return index < 2?0:1; //output - -/* - case audioMasterWantMidi: - return 0; - - case audioMasterProcessEvents: - return 0; // Support of vst events to host is not available -*/ - case audioMasterGetTime: - memset(&_timeInfo, 0, sizeof(_timeInfo)); - _timeInfo.samplePos = 0; - _timeInfo.sampleRate = th?th->sample_rate:0; - return (long)&_timeInfo; - - - case audioMasterTempoAt: - return 0; - - case audioMasterNeedIdle: -// effect->dispatcher(effect, effIdle, 0, 0, NULL, 0.0f); - return 1; - - case audioMasterGetSampleRate: - return th?(long)th->sample_rate:0; - - case audioMasterGetVendorString: // Just fooling version string - strcpy((char*)ptr,"Steinberg"); - return 0; - - case audioMasterGetVendorVersion: - return 5000; // HOST version 5000 - - case audioMasterGetProductString: // Just fooling product string - strcpy((char *)ptr,"Cubase 5.0"); - return 0; - - case audioMasterVendorSpecific: - return 0; - - case audioMasterGetLanguage: - return kVstLangEnglish; - - case audioMasterUpdateDisplay: - FLEXT_LOG("audioMasterUpdateDisplay"); - effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); - return 0; - - case audioMasterCanDo: - if (!strcmp((char *)ptr,"sendVstEvents")) return 1; - else if (!strcmp((char *)ptr,"sendVstMidiEvent")) return 1; - else if (!strcmp((char *)ptr,"sendVstTimeInfo")) return 1; -// "receiveVstEvents", -// "receiveVstMidiEvent", -// "receiveVstTimeInfo", - -// "reportConnectionChanges", -// "acceptIOChanges", -// else if (!strcmp((char*)ptr,"sizeWindow")) return 1; - else if (!strcmp((char*)ptr,"supplyIdle")) return 1; - return -1; - - case audioMasterSetTime: FLEXT_LOG("VST master dispatcher: Set Time");break; - case audioMasterGetNumAutomatableParameters: FLEXT_LOG("VST master dispatcher: GetNumAutPar");break; - case audioMasterGetParameterQuantization: FLEXT_LOG("VST master dispatcher: ParamQuant");break; - case audioMasterIOChanged: FLEXT_LOG("VST master dispatcher: IOchanged");break; - case audioMasterSizeWindow: FLEXT_LOG("VST master dispatcher: Size Window");break; - case audioMasterGetBlockSize: FLEXT_LOG("VST master dispatcher: GetBlockSize");break; - case audioMasterGetInputLatency: FLEXT_LOG("VST master dispatcher: GetInLatency");break; - case audioMasterGetOutputLatency: FLEXT_LOG("VST master dispatcher: GetOutLatency");break; - case audioMasterGetPreviousPlug: FLEXT_LOG("VST master dispatcher: PrevPlug");break; - case audioMasterGetNextPlug: FLEXT_LOG("VST master dispatcher: NextPlug");break; - case audioMasterWillReplaceOrAccumulate: FLEXT_LOG("VST master dispatcher: WillReplace"); break; - case audioMasterGetCurrentProcessLevel: return 0; break; - case audioMasterGetAutomationState: FLEXT_LOG("VST master dispatcher: GetAutState");break; - case audioMasterOfflineStart: FLEXT_LOG("VST master dispatcher: Offlinestart");break; - case audioMasterOfflineRead: FLEXT_LOG("VST master dispatcher: Offlineread");break; - case audioMasterOfflineWrite: FLEXT_LOG("VST master dispatcher: Offlinewrite");break; - case audioMasterOfflineGetCurrentPass: FLEXT_LOG("VST master dispatcher: OfflineGetcurrentpass");break; - case audioMasterOfflineGetCurrentMetaPass: FLEXT_LOG("VST master dispatcher: GetGetCurrentMetapass");break; - case audioMasterSetOutputSampleRate: FLEXT_LOG("VST master dispatcher: Setsamplerate");break; - case audioMasterGetSpeakerArrangement: FLEXT_LOG("VST master dispatcher: Getspeaker");break; - case audioMasterSetIcon: FLEXT_LOG("VST master dispatcher: seticon");break; - case audioMasterOpenWindow: FLEXT_LOG("VST master dispatcher: OpenWindow");break; - case audioMasterCloseWindow: FLEXT_LOG("VST master dispatcher: CloseWindow");break; - case audioMasterGetDirectory: FLEXT_LOG("VST master dispatcher: GetDirectory");break; -// case audioMasterUpdateDisplay: post("VST master dispatcher: audioMasterUpdateDisplay");break; - -#ifdef FLEXT_DEBUG - default: - post("VST master dispatcher: undefed: %d , %d",opcode , effKeysRequired ); -#endif - } - - return 0; -} - -#endif +/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "editor.h"
+#include "vsthost.h"
+#include "AEffectx.h"
+
+#include <ctype.h>
+
+typedef AEffect *(VSTCALLBACK *PVSTMAIN)(audioMasterCallback audioMaster);
+
+
+VSTPlugin::VSTPlugin():
+ h_dll(NULL),hwnd(NULL),_pEffect(NULL),
+ posx(0),posy(0),caption(true),
+ _midichannel(0),queue_size(0),
+ paramnamecnt(0)
+{}
+
+VSTPlugin::~VSTPlugin()
+{
+ Free(); // Call free
+}
+
+void VSTPlugin::FreeVST(MHandle handle)
+{
+#if FLEXT_OS == FLEXT_OS_WIN
+ FreeLibrary(handle);
+#elif FLEXT_OS == FLEXT_OS_MAC
+#else
+#error Platform not supported
+#endif
+}
+
+#if FLEXT_OS == FLEXT_OS_MAC
+OSStatus FSPathMakeFSSpec(
+ const UInt8 *path,
+ FSSpec *spec,
+ Boolean *isDirectory) /* can be NULL */
+{
+ OSStatus result;
+ FSRef ref;
+
+ /* check parameters */
+ require_action(NULL != spec, BadParameter, result = paramErr);
+
+ /* convert the POSIX path to an FSRef */
+ result = FSPathMakeRef(path, &ref, isDirectory);
+ require_noerr(result, FSPathMakeRef);
+
+ /* and then convert the FSRef to an FSSpec */
+ result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
+ require_noerr(result, FSGetCatalogInfo);
+
+FSGetCatalogInfo:
+FSPathMakeRef:
+BadParameter:
+
+ return ( result );
+}
+#endif
+
+int VSTPlugin::Instance(const char *dllname)
+{
+#ifdef FLEXT_DEBUG
+ flext::post("New Plugin 1 - %x",this);
+#endif
+
+ PVSTMAIN pluginmain;
+#if FLEXT_OS == FLEXT_OS_WIN
+ h_dll = LoadLibrary(dllname);
+ if(!h_dll)
+ return VSTINSTANCE_ERR_NO_VALID_FILE;
+
+ pluginmain = (PVSTMAIN)GetProcAddress(h_dll,"main");
+ void *audioMasterFPtr = Master;
+
+#elif FLEXT_OS == FLEXT_OS_MAC
+ short resFileID;
+ FSSpec spec;
+ OSErr err;
+
+ err = FSPathMakeFSSpec(dllname,&spec,NULL);
+ resFileID = FSpOpenResFile(&spec, fsRdPerm);
+ short cResCB = Count1Resources('aEff');
+
+ for(int i = 0; i < cResCB; i++) {
+ Handle codeH;
+ CFragConnectionID connID;
+ Ptr mainAddr;
+ Str255 errName;
+ Str255 fragName;
+ char fragNameCStr[256];
+ short resID;
+ OSType resType;
+
+ codeH = Get1IndResource('aEff', short(i+1));
+ if (!codeH) continue;
+
+ GetResInfo(codeH, &resID, &resType, fragName);
+ DetachResource(codeH);
+ HLock(codeH);
+
+ err = GetMemFragment(*codeH,
+ GetHandleSize(codeH),
+ fragName,
+ kPrivateCFragCopy,
+ &connID, (Ptr *) & mainAddr, errName);
+
+ if (!err) {
+ #ifdef __CFM__
+ pluginmain = (PVSTMAIN)NewMachOFromCFM(mainAddr);
+ #else
+ pluginmain = (PVSTMAIN)mainAddr;
+ #endif
+ }
+ }
+
+ CloseResFile(resFileID);
+
+ void *audioMasterFPtr =
+#ifdef __CFM__
+ NewCFMFromMachO(Master);
+#else
+ Master;
+#endif
+
+#else
+#error Platform not supported
+#endif
+
+ if(!pluginmain) {
+ FreeVST(h_dll);
+ _pEffect = NULL;
+ return VSTINSTANCE_ERR_NO_VST_PLUGIN;
+ }
+
+ //This calls the "main" function and receives the pointer to the AEffect structure.
+ _pEffect = pluginmain((audioMasterCallback)audioMasterFPtr);
+
+#ifdef __MACOSX__
+#ifdef __CFM__
+ DisposeCFMFromMachO(audioMasterFPtr);
+ DisposeMachOFromCFM(pluginmain);
+#endif
+#endif
+
+
+ if(!_pEffect || _pEffect->magic != kEffectMagic) {
+ post("VST plugin : Unable to create effect");
+
+ _pEffect = NULL;
+ FreeVST(h_dll);
+ h_dll = NULL;
+ return VSTINSTANCE_ERR_REJECTED;
+ }
+
+ //init plugin
+ _pEffect->user = this;
+
+ long ret = Dispatch( effOpen );
+ FLEXT_ASSERT(!ret);
+
+ ret = Dispatch( effIdentify);
+ FLEXT_ASSERT(ret == 'NvEf');
+
+ *_sProductName = 0;
+ ret = Dispatch( effGetProductString, 0, 0, _sProductName, 0.0f);
+ if(!*_sProductName) {
+ // no product name given by plugin -> extract it from the filename
+
+ std::string str1(dllname);
+ std::string::size_type slpos = str1.rfind('\\');
+ if(slpos == std::string::npos) {
+ slpos = str1.rfind('/');
+ if(slpos == std::string::npos)
+ slpos = 0;
+ else
+ ++slpos;
+ }
+ else
+ ++slpos;
+ std::string str2 = str1.substr(slpos);
+ int snip = str2.find('.');
+ if( snip != std::string::npos )
+ str1 = str2.substr(0,snip);
+ else
+ str1 = str2;
+ strcpy(_sProductName,str1.c_str());
+ }
+
+ if(*_sProductName) {
+ char tmp[512];
+ sprintf(tmp,"vst~ - %s",_sProductName);
+ title = tmp;
+ }
+ else
+ title = "vst~";
+
+ *_sVendorName = 0;
+ Dispatch( effGetVendorString, 0, 0,_sVendorName, 0.0f);
+
+ _sDllName = dllname;
+
+#ifdef FLEXT_DEBUG
+ flext::post("New Plugin 2 - %x",this);
+#endif
+
+ return VSTINSTANCE_NO_ERROR;
+}
+
+
+/*
+void VSTPlugin::Create(VSTPlugin *plug)
+{
+ h_dll = plug->h_dll;
+ _pEffect = plug->_pEffect;
+ _pEffect->user = this;
+
+ Dispatch( effMainsChanged, 0, 1);
+// strcpy(_editName,plug->_editName); On current implementation, this replaces the right one.
+ strcpy(_sProductName,plug->_sProductName);
+ strcpy(_sVendorName,plug->_sVendorName);
+
+ _sDllName = new char[strlen(plug->_sDllName)+1];
+ strcpy(_sDllName,plug->_sDllName);
+
+ _isSynth=plug->_isSynth;
+ _version=plug->_version;
+
+ plug->instantiated=false; // We are "stoling" the plugin from the "plug" object so this
+ // is just a "trick" so that when destructing the "plug", it
+ // doesn't unload the Dll.
+ instantiated=true;
+}
+*/
+
+void VSTPlugin::Free() // Called also in destruction
+{
+ if(Is()) {
+ if(IsEdited()) StopEditor(this);
+
+ // shut down plugin
+ Dispatch(effMainsChanged, 0, 0);
+ Dispatch(effClose);
+
+#ifdef FLEXT_DEBUG
+ flext::post("Free Plugin 1 - %x",this);
+#endif
+
+ _pEffect = NULL;
+
+ // \TODO
+ // Here, we really have to wait until the editor thread has terminated
+ // otherwise WM_DESTROY etc. messages may still be pending
+ // in other words: this is a design flaw
+ // There should be a data stub accessible from the plugin object and the thread
+ // holding the necessary data, so that both can operate independently
+
+ if(h_dll) {
+ FreeVST(h_dll);
+ h_dll = NULL;
+ }
+
+#ifdef FLEXT_DEBUG
+ flext::post("Free Plugin 2 - %x",this);
+#endif
+ }
+}
+
+void VSTPlugin::DspInit(float samplerate,int blocksize)
+{
+ // sample rate and block size must _first_ be set
+ Dispatch(effSetSampleRate, 0, 0,NULL,samplerate);
+ Dispatch(effSetBlockSize, 0, blocksize);
+ // than signal that mains have changed!
+ Dispatch(effMainsChanged, 0, 1);
+}
+
+static void striptrail(char *txt)
+{
+ // strip trailing whitespace
+ for(int i = strlen(txt)-1; i >= 0; --i)
+ // cast to unsigned char since isspace functions don't want characters like 0x80 = -128
+ if(isspace(((unsigned char *)txt)[i])) txt[i] = 0;
+}
+
+void VSTPlugin::GetParamName(int numparam,char *name) const
+{
+ if(numparam < GetNumParams()) {
+ name[0] = 0;
+ Dispatch(effGetParamName,numparam,0,name,0.0f);
+ striptrail(name);
+ }
+ else
+ name[0] = 0;
+}
+
+bool VSTPlugin::SetParamFloat(int parameter,float value)
+{
+ if(Is() && parameter >= 0 && parameter < GetNumParams()) {
+ _pEffect->setParameter(_pEffect,parameter,value);
+ return true;
+ }
+ else
+ return false;
+}
+
+void VSTPlugin::GetParamValue(int numparam,char *parval) const
+{
+ if(Is()) {
+ if(numparam < GetNumParams()) {
+ // how many chars needed?
+ char par_display[64]; par_display[0] = 0;
+ Dispatch(effGetParamDisplay,numparam,0,par_display,0.0f);
+// if(par_display[7]) par_display[8] = 0; // set trailing zero
+
+ // how many chars needed?
+ char par_label[64]; par_label[0] = 0;
+ Dispatch(effGetParamLabel,numparam,0,par_label,0.0f);
+ striptrail(par_label);
+// if(par_label[7]) par_label[8] = 0; // set trailing zero
+
+ sprintf(parval,"%s%s",par_display,par_label);
+ }
+ else
+ strcpy(parval,"Index out of range");
+ }
+ else
+ strcpy(parval,"Plugin not loaded");
+}
+
+float VSTPlugin::GetParamValue(int numparam) const
+{
+ if(Is() && numparam < GetNumParams())
+ return _pEffect->getParameter(_pEffect, numparam);
+ else
+ return -1.0;
+}
+
+void VSTPlugin::ScanParams(int cnt)
+{
+ if(cnt < 0) cnt = GetNumParams();
+ if(paramnamecnt >= cnt) return;
+ if(cnt >= GetNumParams()) cnt = GetNumParams();
+
+ char name[64];
+ for(int i = paramnamecnt; i < cnt; ++i) {
+ GetParamName(i,name);
+ if(*name) paramnames[std::string(name)] = i;
+ }
+ paramnamecnt = cnt;
+}
+
+int VSTPlugin::GetParamIx(const char *p) const
+{
+ NameMap::const_iterator it = paramnames.find(std::string(p));
+ return it == paramnames.end()?-1:it->second;
+}
+
+void VSTPlugin::Edit(bool open)
+{
+ if(Is()) {
+ if(open) {
+ if(HasEditor() && !IsEdited())
+ StartEditor(this);
+ }
+ else if(IsEdited())
+ StopEditor(this);
+ }
+}
+
+void VSTPlugin::StartEditing(WHandle h)
+{
+ FLEXT_ASSERT(h != NULL);
+ Dispatch(effEditOpen,0,0,hwnd = h);
+// Dispatch(effEditTop);
+
+ TitleEditor(this,title.c_str());
+}
+
+void VSTPlugin::StopEditing()
+{
+ if(Is()) {
+ Dispatch(effEditClose);
+ hwnd = NULL;
+ }
+}
+
+void VSTPlugin::Visible(bool vis)
+{
+ if(Is() && IsEdited()) ShowEditor(this,vis);
+}
+
+bool VSTPlugin::IsVisible() const
+{
+ return Is() && IsEdited() && IsEditorShown(this);
+}
+
+bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2)
+{
+ if(Is()) {
+ VstMidiEvent* pevent = &midievent[queue_size];
+
+ pevent->type = kVstMidiType;
+ pevent->byteSize = 24;
+ pevent->deltaFrames = 0;
+ pevent->flags = 0;
+ pevent->detune = 0;
+ pevent->noteLength = 0;
+ pevent->noteOffset = 0;
+ pevent->reserved1 = 0;
+ pevent->reserved2 = 0;
+ pevent->noteOffVelocity = 0;
+ pevent->midiData[0] = data0;
+ pevent->midiData[1] = data1;
+ pevent->midiData[2] = data2;
+ pevent->midiData[3] = 0;
+
+ if ( queue_size < MAX_EVENTS ) queue_size++;
+ SendMidi();
+ return true;
+ }
+ else return false;
+}
+
+
+void VSTPlugin::SendMidi()
+{
+ if(Is() && queue_size > 0) {
+ // Prepare MIDI events and free queue dispatching all events
+ events.numEvents = queue_size;
+ events.reserved = 0;
+ for(int q = 0; q < queue_size; q++)
+ events.events[q] = (VstEvent*)&midievent[q];
+
+ Dispatch(effProcessEvents, 0, 0, &events, 0.0f);
+ queue_size = 0;
+ }
+}
+
+static int range(int value,int mn = 0,int mx = 127)
+{
+ return value < mn?mn:(value > mx?mx:value);
+}
+
+bool VSTPlugin::AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel)
+{
+ return AddMIDI((char)MIDI_NOTEON | midichannel,note,speed);
+}
+
+bool VSTPlugin::AddNoteOff( unsigned char note,unsigned char midichannel)
+{
+ return AddMIDI((char)MIDI_NOTEOFF | midichannel,note,0);
+}
+
+void VSTPlugin::AddAftertouch(int value)
+{
+ AddMIDI( (char)MIDI_NOTEOFF | _midichannel , range(value) );
+}
+
+void VSTPlugin::AddPitchBend(int value)
+{
+ AddMIDI( MIDI_PITCHBEND + (_midichannel & 0xf) , ((value>>7) & 127), (value & 127));
+}
+
+void VSTPlugin::AddProgramChange(int value)
+{
+ AddMIDI( MIDI_PROGRAMCHANGE + (_midichannel & 0xf), range(value), 0);
+}
+
+void VSTPlugin::AddControlChange(int control, int value)
+{
+ AddMIDI( MIDI_CONTROLCHANGE + (_midichannel & 0xf), range(control), range(value));
+}
+
+
+bool VSTPlugin::GetProgramName( int cat , int p, char *buf) const
+{
+ buf[0] = 0;
+ int parameter = p;
+ if(parameter < GetNumPrograms() && cat < GetNumCategories()) {
+ Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f);
+ striptrail(buf);
+ return true;
+ }
+ else
+ return false;
+}
+
+void VSTPlugin::SetPos(int x,int y,bool upd)
+{
+ if(Is()) {
+ posx = x; posy = y;
+ if(upd && IsEdited()) MoveEditor(this,posx,posy);
+ }
+}
+
+void VSTPlugin::SetCaption(bool c)
+{
+ if(Is()) {
+ caption = c;
+ if(IsEdited()) CaptionEditor(this,c);
+ }
+}
+
+void VSTPlugin::SetTitle(const char *t)
+{
+ if(Is()) {
+ title = t;
+ if(IsEdited()) TitleEditor(this,t);
+ }
+}
+
+void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes )
+{
+ _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes );
+}
+
+void VSTPlugin::process( float **inputs, float **outputs, long sampleframes )
+{
+ _pEffect->process( _pEffect , inputs , outputs , sampleframes );
+}
+
+#if 1
+
+// Host callback dispatcher
+long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+{
+#if 0
+ audioMasterEnum op = (audioMasterEnum)opcode;
+ audioMasterEnumx opx = (audioMasterEnumx)opcode;
+#endif
+
+#ifdef FLEXT_DEBUG
+// post("VST -> host: Eff = 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
+#endif
+
+ switch (opcode) {
+ case audioMasterAutomate: // 0
+#ifdef FLEXT_DEBUG
+ post("Automate index=%li value=%li opt=%f",index,value,opt);
+#endif
+ // index, value given
+ //! \todo set effect parameter
+ return 0;
+ case audioMasterVersion: // 1
+ // support VST 2.3
+// return 2300;
+ return 2;
+ case audioMasterCurrentId: // 2
+ return 0;
+ case audioMasterIdle: // 3
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+ case audioMasterPinConnected: // 4
+ //! \todo set connection state correctly (if possible..)
+ // index=pin, value=0..input, else..output
+#ifdef FLEXT_DEBUG
+ post("Pin connected pin=%li conn=%li",index,value);
+#endif
+ return 0; // 0 means connected
+ case audioMasterWantMidi: // 6
+#ifdef FLEXT_DEBUG
+ post("Want MIDI = %li",value);
+#endif
+ return 0; // VST header says: "currently ignored"
+ case audioMasterGetTime: // 7
+ return 0; // not supported
+ case audioMasterProcessEvents: { // 8
+ // VST event data from plugin
+ VstEvent *ev = static_cast<VstEvent *>(ptr);
+ if(ev->type == kVstMidiType) {
+ VstMidiEvent *mev = static_cast<VstMidiEvent *>(ptr);
+#ifdef FLEXT_DEBUG
+ if(mev->byteSize == 24)
+ post("MIDI event delta=%li len=%li offs=%li detune=%i offvel=%i",mev->deltaFrames,mev->noteLength,mev->noteOffset,(int)mev->detune,(int)mev->noteOffVelocity);
+ else
+ // has incorrect size
+ post("MIDI event");
+#endif
+ }
+ else {
+#ifdef FLEXT_DEBUG
+ post("VST event type=%li",ev->type);
+#endif
+ }
+ return 1;
+ }
+ case audioMasterSetTime: { // 9
+ VstTimeInfo *tminfo = static_cast<VstTimeInfo *>(ptr);
+#ifdef FLEXT_DEBUG
+ post("TimeInfo pos=%lf rate=%lf filter=%li",tminfo->samplePos,tminfo->sampleRate,value);
+#endif
+ return 0; // not supported
+ }
+ case audioMasterTempoAt: // 10
+ return 0; // not supported
+ case audioMasterGetNumAutomatableParameters: // 11
+ return 0; // not supported
+ case audioMasterSizeWindow: // 15
+ return 0;
+// case audioMasterGetSampleRate: // 16
+// case audioMasterGetBlockSize: // 17
+ case audioMasterGetCurrentProcessLevel: // 23
+ // return thread state
+ return flext::GetThreadId() == flext::GetSysThreadId()?2:1;
+ case audioMasterGetVendorString: // 32
+ strcpy((char*)ptr,"grrrr.org");
+ return 0;
+ case audioMasterGetProductString: // 33
+ strcpy((char *)ptr,"vst~ host external");
+ return 0;
+ case audioMasterGetVendorVersion: // 34
+ return 100;
+ case audioMasterCanDo: // 37
+#ifdef FLEXT_DEBUG
+ post("\taudioMasterCanDo PTR = %s",ptr);
+#endif
+ if(!strcmp((char *)ptr,"sendVstEvents"))
+ return 1;
+ else if(!strcmp((char *)ptr,"sendVstMidiEvent"))
+ return 1;
+ else if(!strcmp((char *)ptr,"sendVstTimeInfo"))
+ return 1; // NOT YET
+ else if(!strcmp((char *)ptr,"receiveVstEvents"))
+ return 1;
+ else if(!strcmp((char *)ptr,"receiveVstMidiEvent"))
+ return 1;
+ else if(!strcmp((char *)ptr,"receiveVstTimeInfo"))
+ return 1; // NOT YET
+ else if(!strcmp((char *)ptr,"reportConnectionChanges"))
+ return 0; // \TODO PD has hard times supporting that...
+ else if(!strcmp((char *)ptr,"acceptIOChanges"))
+ return 0; // \TODO what does this means exactly?
+ else if(!strcmp((char *)ptr,"supplyIdle"))
+ return 1;
+ else if(!strcmp((char *)ptr,"sizeWindow"))
+ return 1;
+ else if(!strcmp((char *)ptr,"supportShell"))
+ return 0; // NOT YET!
+ else if(!strcmp((char *)ptr,"offline"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"asyncProcessing"))
+ return 0; // not supported
+
+ return 0; // not supported
+ case audioMasterGetLanguage: // 38
+ return kVstLangEnglish;
+ case audioMasterGetDirectory: // 41
+ // return full path of plugin
+ return 0; // not supported
+ case audioMasterUpdateDisplay: // 42
+#ifdef FLEXT_DEBUG
+ post("UPDATE DISPLAY");
+#endif
+ return 0;
+ default:
+#ifdef FLEXT_DEBUG
+ post("Unknown opcode %li",opcode);
+#endif
+ return 0;
+ }
+}
+
+#else
+
+// Host callback dispatcher
+long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+{
+ VSTPlugin *th = effect?(VSTPlugin *)effect->user:NULL;
+ if(!th) FLEXT_LOG("No this");
+
+#ifdef FLEXT_DEBUG
+ if(opcode != audioMasterGetTime)
+ post("VST plugin call to host dispatcher: Eff: 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
+ //st( "audioMasterWantMidi %d " , audioMasterWantMidi);
+#endif
+
+ // Support opcodes
+ switch(opcode)
+ {
+ case audioMasterAutomate:
+ return 0; // index, value, returns 0
+
+ case audioMasterVersion:
+ return 2; // vst version, currently 7 (0 for older)
+
+ case audioMasterCurrentId:
+ return 'AASH'; // returns the unique id of a plug that's currently loading
+
+ case audioMasterIdle:
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0; // call application idle routine (this will call effEditIdle for all open editors too)
+
+ case audioMasterPinConnected:
+ if(value == 0)
+ return index < 2?0:1; //input
+ else
+ return index < 2?0:1; //output
+
+/*
+ case audioMasterWantMidi:
+ return 0;
+
+ case audioMasterProcessEvents:
+ return 0; // Support of vst events to host is not available
+*/
+ case audioMasterGetTime:
+ memset(&_timeInfo, 0, sizeof(_timeInfo));
+ _timeInfo.samplePos = 0;
+ _timeInfo.sampleRate = th?th->sample_rate:0;
+ return (long)&_timeInfo;
+
+
+ case audioMasterTempoAt:
+ return 0;
+
+ case audioMasterNeedIdle:
+// effect->dispatcher(effect, effIdle, 0, 0, NULL, 0.0f);
+ return 1;
+
+ case audioMasterGetSampleRate:
+ return th?(long)th->sample_rate:0;
+
+ case audioMasterGetVendorString: // Just fooling version string
+ strcpy((char*)ptr,"Steinberg");
+ return 0;
+
+ case audioMasterGetVendorVersion:
+ return 5000; // HOST version 5000
+
+ case audioMasterGetProductString: // Just fooling product string
+ strcpy((char *)ptr,"Cubase 5.0");
+ return 0;
+
+ case audioMasterVendorSpecific:
+ return 0;
+
+ case audioMasterGetLanguage:
+ return kVstLangEnglish;
+
+ case audioMasterUpdateDisplay:
+ FLEXT_LOG("audioMasterUpdateDisplay");
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+ case audioMasterCanDo:
+ if (!strcmp((char *)ptr,"sendVstEvents")) return 1;
+ else if (!strcmp((char *)ptr,"sendVstMidiEvent")) return 1;
+ else if (!strcmp((char *)ptr,"sendVstTimeInfo")) return 1;
+// "receiveVstEvents",
+// "receiveVstMidiEvent",
+// "receiveVstTimeInfo",
+
+// "reportConnectionChanges",
+// "acceptIOChanges",
+// else if (!strcmp((char*)ptr,"sizeWindow")) return 1;
+ else if (!strcmp((char*)ptr,"supplyIdle")) return 1;
+ return -1;
+
+ case audioMasterSetTime: FLEXT_LOG("VST master dispatcher: Set Time");break;
+ case audioMasterGetNumAutomatableParameters: FLEXT_LOG("VST master dispatcher: GetNumAutPar");break;
+ case audioMasterGetParameterQuantization: FLEXT_LOG("VST master dispatcher: ParamQuant");break;
+ case audioMasterIOChanged: FLEXT_LOG("VST master dispatcher: IOchanged");break;
+ case audioMasterSizeWindow: FLEXT_LOG("VST master dispatcher: Size Window");break;
+ case audioMasterGetBlockSize: FLEXT_LOG("VST master dispatcher: GetBlockSize");break;
+ case audioMasterGetInputLatency: FLEXT_LOG("VST master dispatcher: GetInLatency");break;
+ case audioMasterGetOutputLatency: FLEXT_LOG("VST master dispatcher: GetOutLatency");break;
+ case audioMasterGetPreviousPlug: FLEXT_LOG("VST master dispatcher: PrevPlug");break;
+ case audioMasterGetNextPlug: FLEXT_LOG("VST master dispatcher: NextPlug");break;
+ case audioMasterWillReplaceOrAccumulate: FLEXT_LOG("VST master dispatcher: WillReplace"); break;
+ case audioMasterGetCurrentProcessLevel: return 0; break;
+ case audioMasterGetAutomationState: FLEXT_LOG("VST master dispatcher: GetAutState");break;
+ case audioMasterOfflineStart: FLEXT_LOG("VST master dispatcher: Offlinestart");break;
+ case audioMasterOfflineRead: FLEXT_LOG("VST master dispatcher: Offlineread");break;
+ case audioMasterOfflineWrite: FLEXT_LOG("VST master dispatcher: Offlinewrite");break;
+ case audioMasterOfflineGetCurrentPass: FLEXT_LOG("VST master dispatcher: OfflineGetcurrentpass");break;
+ case audioMasterOfflineGetCurrentMetaPass: FLEXT_LOG("VST master dispatcher: GetGetCurrentMetapass");break;
+ case audioMasterSetOutputSampleRate: FLEXT_LOG("VST master dispatcher: Setsamplerate");break;
+ case audioMasterGetSpeakerArrangement: FLEXT_LOG("VST master dispatcher: Getspeaker");break;
+ case audioMasterSetIcon: FLEXT_LOG("VST master dispatcher: seticon");break;
+ case audioMasterOpenWindow: FLEXT_LOG("VST master dispatcher: OpenWindow");break;
+ case audioMasterCloseWindow: FLEXT_LOG("VST master dispatcher: CloseWindow");break;
+ case audioMasterGetDirectory: FLEXT_LOG("VST master dispatcher: GetDirectory");break;
+// case audioMasterUpdateDisplay: post("VST master dispatcher: audioMasterUpdateDisplay");break;
+
+#ifdef FLEXT_DEBUG
+ default:
+ post("VST master dispatcher: undefed: %d , %d",opcode , effKeysRequired );
+#endif
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/externals/grill/vst/src/VstHost.h b/externals/grill/vst/src/vsthost.h index ef466a87..f61aa87b 100644 --- a/externals/grill/vst/src/VstHost.h +++ b/externals/grill/vst/src/vsthost.h @@ -1,193 +1,190 @@ -/* -vst~ - VST plugin object for PD -based on the work of Jarno Seppänen and Mark Williamson - -Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net) -For information on usage and redistribution, and for a DISCLAIMER OF ALL -WARRANTIES, see the file, "license.txt," in this distribution. -*/ - -#ifndef __VSTHOST_H -#define __VSTHOST_H - -#include <flext.h> -#include "AEffectx.h" -#include "AEffEditor.hpp" -#include <string> - -#if FLEXT_OS == FLEXT_OS_WIN -#include <windows.h> -typedef HWND WHandle; -#elif FLEXT_OS == FLEXT_OS_MAC -#include <CoreServices/CoreServices.h> -typedef Handle WHandle; -#else -#error Platform not supported! -#endif - - -#define MAX_EVENTS 64 -#define MAX_INOUTS 8 - -#define VSTINSTANCE_ERR_NO_VALID_FILE -1 -#define VSTINSTANCE_ERR_NO_VST_PLUGIN -2 -#define VSTINSTANCE_ERR_REJECTED -3 -#define VSTINSTANCE_NO_ERROR 0 - -#define MIDI_NOTEON 144 -#define MIDI_NOTEOFF 128 -#define MIDI_POLYAFTERTOUCH 160 -#define MIDI_CONTROLCHANGE 176 -#define MIDI_PROGRAMCHANGE 192 -#define MIDI_AFTERTOUCH 208 -#define MIDI_PITCHBEND 224 - - -class VSTPlugin: - public flext -{ -public: - - VSTPlugin(); - ~VSTPlugin(); - - int Instance(const char *dllname); -// void Create(VSTPlugin *plug); - void Free(); - void DspInit(float samplerate,int blocksize); - - bool Is() const { return _pEffect != NULL; } - - long GetVersion() const { return _pEffect?_pEffect->version:0; } - - bool IsSynth() const { return HasFlags(effFlagsIsSynth); } - bool IsReplacing() const { return HasFlags(effFlagsCanReplacing); } - bool HasEditor() const { return HasFlags(effFlagsHasEditor); } - - const char *GetName() const { return _sProductName; } - const char *GetVendorName() const { return _sVendorName; } - const char *GetDllName() const { return _sDllName.c_str(); } - - int GetNumInputs() const { return _pEffect?_pEffect->numInputs:0; } - int GetNumOutputs() const { return _pEffect?_pEffect->numOutputs:0; } - - int GetNumParams() const { return _pEffect?_pEffect->numParams:0; } - void GetParamName(int numparam,char *name) const; - void GetParamValue(int numparam,char *parval) const; - float GetParamValue(int numparam) const; - - // scan plugin names (can take a _long_ time!!) - void ScanParams(int i = -1); - // get number of scanned parameters - int ScannedParams() const { return paramnamecnt; } - // get index of named (scanned) parameter... -1 if not found - int GetParamIx(const char *p) const; - - bool SetParamFloat(int parameter, float value); - bool SetParamInt(int parameter, int value) { return SetParamFloat(parameter,value/65535.0f); } - - void SetCurrentProgram(int prg) { Dispatch(effSetProgram,0,prg); } - int GetCurrentProgram() const { return Dispatch(effGetProgram); } - int GetNumPrograms() const { return _pEffect->numPrograms; } - - int GetNumCategories() const { return Dispatch(effGetNumProgramCategories); } - bool GetProgramName( int cat, int p , char* buf) const; - - - bool AddMIDI(unsigned char data0,unsigned char data1=0,unsigned char data2=0); - - bool AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel=0); - bool AddNoteOff( unsigned char note,unsigned char midichannel=0); - - void AddControlChange( int control , int value ); - void AddProgramChange( int value ); - void AddPitchBend( int value ); - void AddAftertouch( int value ); - - void Edit(bool open); - - void StartEditing(WHandle h ); - void StopEditing(); - bool IsEdited() const { return hwnd != NULL; } - WHandle EditorHandle() const { return hwnd; } - - void GetEditorRect(ERect &er) const { ERect *r; Dispatch(effEditGetRect,0,0,&r); er = *r; } - void EditorIdle() { Dispatch(effEditIdle); } - - void Visible(bool vis); - bool IsVisible() const; - - void Paint(ERect &r) const { Dispatch(effEditDraw,0,0,&r); } - - void processReplacing( float **inputs, float **outputs, long sampleframes ); - void process( float **inputs, float **outputs, long sampleframes ); - - long Dispatch(long opCode, long index = 0, long value = 0, void *ptr = NULL, float opt = 0) const - { - return Is()?_pEffect->dispatcher(_pEffect, opCode, index, value, ptr, opt):0; - } - - static long VSTCALLBACK Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt); - - void SetPos(int x,int y,bool upd = true); - void SetX(int x,bool upd = true) { SetPos(x,posy,upd); } - void SetY(int y,bool upd = true) { SetPos(posx,y,upd); } - int GetX() const { return posx; } - int GetY() const { return posy; } - void SetCaption(bool b); - bool GetCaption() const { return caption; } - void SetTitle(const char *t); - const char *GetTitle() const { return title.c_str(); } - -protected: - -#if FLEXT_OS == FLEXT_OS_WIN - HMODULE h_dll; -#elif FLEXT_OS == FLEXT_OS_MAC - void *h_dll; -#else -#error -#endif - - WHandle hwnd; - - AEffect *_pEffect; - - inline long GetFlags() const { return _pEffect?_pEffect->flags:0; } - inline bool HasFlags(long msk) const { return _pEffect && (_pEffect->flags&msk); } - - char _sProductName[300]; - char _sVendorName[300]; - std::string _sDllName; // Contains dll name - - struct NameCmp: - std::less<std::string> - { - bool operator()(const std::string &a,const std::string &b) const { return a.compare(b) < 0; } - }; - - typedef std::map<std::string,int,NameCmp> NameMap; - int paramnamecnt; - NameMap paramnames; - -/* - float *inputs[MAX_INOUTS]; - float *outputs[MAX_INOUTS]; -*/ - -// static VstTimeInfo _timeInfo; - VstMidiEvent midievent[MAX_EVENTS]; - VstEvents events; - int queue_size; - -// float sample_rate; - - void SendMidi(); - char _midichannel; - - int posx,posy; // Window position - bool caption; // Window border - std::string title; // Window title -}; - -#endif +/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#ifndef __VSTHOST_H
+#define __VSTHOST_H
+
+#include <flext.h>
+#include "AEffectx.h"
+#include "AEffEditor.hpp"
+#include <string>
+
+#if FLEXT_OS == FLEXT_OS_WIN
+#include <windows.h>
+typedef HWND WHandle;
+typedef HMODULE MHandle;
+#elif FLEXT_OS == FLEXT_OS_MAC
+#include <CoreServices/CoreServices.h>
+typedef Handle WHandle;
+typedef void *MHandle;
+#else
+#error Platform not supported!
+#endif
+
+
+#define MAX_EVENTS 64
+#define MAX_INOUTS 8
+
+#define VSTINSTANCE_ERR_NO_VALID_FILE -1
+#define VSTINSTANCE_ERR_NO_VST_PLUGIN -2
+#define VSTINSTANCE_ERR_REJECTED -3
+#define VSTINSTANCE_NO_ERROR 0
+
+#define MIDI_NOTEON 144
+#define MIDI_NOTEOFF 128
+#define MIDI_POLYAFTERTOUCH 160
+#define MIDI_CONTROLCHANGE 176
+#define MIDI_PROGRAMCHANGE 192
+#define MIDI_AFTERTOUCH 208
+#define MIDI_PITCHBEND 224
+
+
+class VSTPlugin:
+ public flext
+{
+public:
+
+ VSTPlugin();
+ ~VSTPlugin();
+
+ int Instance(const char *dllname);
+// void Create(VSTPlugin *plug);
+ void Free();
+ void DspInit(float samplerate,int blocksize);
+
+ bool Is() const { return _pEffect != NULL; }
+
+ long GetVersion() const { return _pEffect?_pEffect->version:0; }
+
+ bool IsSynth() const { return HasFlags(effFlagsIsSynth); }
+ bool IsReplacing() const { return HasFlags(effFlagsCanReplacing); }
+ bool HasEditor() const { return HasFlags(effFlagsHasEditor); }
+
+ const char *GetName() const { return _sProductName; }
+ const char *GetVendorName() const { return _sVendorName; }
+ const char *GetDllName() const { return _sDllName.c_str(); }
+
+ int GetNumInputs() const { return _pEffect?_pEffect->numInputs:0; }
+ int GetNumOutputs() const { return _pEffect?_pEffect->numOutputs:0; }
+
+ int GetNumParams() const { return _pEffect?_pEffect->numParams:0; }
+ void GetParamName(int numparam,char *name) const;
+ void GetParamValue(int numparam,char *parval) const;
+ float GetParamValue(int numparam) const;
+
+ // scan plugin names (can take a _long_ time!!)
+ void ScanParams(int i = -1);
+ // get number of scanned parameters
+ int ScannedParams() const { return paramnamecnt; }
+ // get index of named (scanned) parameter... -1 if not found
+ int GetParamIx(const char *p) const;
+
+ bool SetParamFloat(int parameter, float value);
+ bool SetParamInt(int parameter, int value) { return SetParamFloat(parameter,value/65535.0f); }
+
+ void SetCurrentProgram(int prg) { Dispatch(effSetProgram,0,prg); }
+ int GetCurrentProgram() const { return Dispatch(effGetProgram); }
+ int GetNumPrograms() const { return _pEffect->numPrograms; }
+
+ int GetNumCategories() const { return Dispatch(effGetNumProgramCategories); }
+ bool GetProgramName( int cat, int p , char* buf) const;
+
+
+ bool AddMIDI(unsigned char data0,unsigned char data1=0,unsigned char data2=0);
+
+ bool AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel=0);
+ bool AddNoteOff( unsigned char note,unsigned char midichannel=0);
+
+ void AddControlChange( int control , int value );
+ void AddProgramChange( int value );
+ void AddPitchBend( int value );
+ void AddAftertouch( int value );
+
+ void Edit(bool open);
+
+ void StartEditing(WHandle h );
+ void StopEditing();
+ bool IsEdited() const { return hwnd != NULL; }
+ WHandle EditorHandle() const { return hwnd; }
+
+ void GetEditorRect(ERect &er) const { ERect *r; Dispatch(effEditGetRect,0,0,&r); er = *r; }
+ void EditorIdle() { Dispatch(effEditIdle); }
+
+ void Visible(bool vis);
+ bool IsVisible() const;
+
+ void Paint(ERect &r) const { Dispatch(effEditDraw,0,0,&r); }
+
+ void processReplacing( float **inputs, float **outputs, long sampleframes );
+ void process( float **inputs, float **outputs, long sampleframes );
+
+ long Dispatch(long opCode, long index = 0, long value = 0, void *ptr = NULL, float opt = 0) const
+ {
+ return Is()?_pEffect->dispatcher(_pEffect, opCode, index, value, ptr, opt):0;
+ }
+
+ static long VSTCALLBACK Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt);
+
+ void SetPos(int x,int y,bool upd = true);
+ void SetX(int x,bool upd = true) { SetPos(x,posy,upd); }
+ void SetY(int y,bool upd = true) { SetPos(posx,y,upd); }
+ int GetX() const { return posx; }
+ int GetY() const { return posy; }
+ void SetCaption(bool b);
+ bool GetCaption() const { return caption; }
+ void SetTitle(const char *t);
+ const char *GetTitle() const { return title.c_str(); }
+
+protected:
+
+ MHandle h_dll;
+ WHandle hwnd;
+
+ AEffect *_pEffect;
+
+ static void FreeVST(MHandle handle);
+
+ inline long GetFlags() const { return _pEffect?_pEffect->flags:0; }
+ inline bool HasFlags(long msk) const { return _pEffect && (_pEffect->flags&msk); }
+
+ char _sProductName[300];
+ char _sVendorName[300];
+ std::string _sDllName; // Contains dll name
+
+ struct NameCmp:
+ std::less<std::string>
+ {
+ bool operator()(const std::string &a,const std::string &b) const { return a.compare(b) < 0; }
+ };
+
+ typedef std::map<std::string,int,NameCmp> NameMap;
+ int paramnamecnt;
+ NameMap paramnames;
+
+/*
+ float *inputs[MAX_INOUTS];
+ float *outputs[MAX_INOUTS];
+*/
+
+// static VstTimeInfo _timeInfo;
+ VstMidiEvent midievent[MAX_EVENTS];
+ VstEvents events;
+ int queue_size;
+
+// float sample_rate;
+
+ void SendMidi();
+ char _midichannel;
+
+ int posx,posy; // Window position
+ bool caption; // Window border
+ std::string title; // Window title
+};
+
+#endif
|