aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/vst/src/vstmaster.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-11 04:58:01 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-11 04:58:01 +0000
commit27da08004c5f024a0f35e3cb4c2b3942548ebcfa (patch)
treec89092a5e8d13c11719b7975b9557efbf3ca131f /externals/grill/vst/src/vstmaster.cpp
parent467591c8ba03dbd60ceada93482460de3b888838 (diff)
restructured VSThost code
better shell support fix for build system update for flext build systemcleanups VSTTime info added event processing (like Midi in) svn path=/trunk/; revision=2617
Diffstat (limited to 'externals/grill/vst/src/vstmaster.cpp')
-rw-r--r--externals/grill/vst/src/vstmaster.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/externals/grill/vst/src/vstmaster.cpp b/externals/grill/vst/src/vstmaster.cpp
new file mode 100644
index 00000000..0395fb65
--- /dev/null
+++ b/externals/grill/vst/src/vstmaster.cpp
@@ -0,0 +1,288 @@
+/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "vsthost.h"
+
+static const int VST_VERSION = 100;
+static const char *vendor = "grrrr.org";
+static const char *product = "vst~";
+
+
+void VSTPlugin::ProcessEvent(const VstEvent &ev)
+{
+ if(!responder) return;
+
+ if(ev.type == kVstMidiType) {
+ const VstMidiEvent &mev = (const VstMidiEvent &)ev;
+ t_atom lst[10];
+ SetSymbol(lst[0],sym_evmidi);
+ int midi = ((unsigned char)mev.midiData[0]>>4)-8;
+ FLEXT_ASSERT(midi >= 0 && midi < 8);
+ SetSymbol(lst[1],sym_midi[midi]);
+ SetInt(lst[2],(unsigned char)mev.midiData[0]&0x0f);
+ SetInt(lst[3],(unsigned char)mev.midiData[1]);
+ SetInt(lst[4],(unsigned char)mev.midiData[2]);
+ // what about running status? (obviously not possible)
+ SetInt(lst[5],mev.deltaFrames);
+ SetInt(lst[6],mev.noteLength);
+ SetInt(lst[7],mev.noteOffset);
+ SetInt(lst[8],(int)mev.detune);
+ SetInt(lst[9],(int)mev.noteOffVelocity);
+ responder->Respond(sym_event,9,lst);
+ }
+ else {
+ const t_symbol *sym;
+ if(ev.type == kVstAudioType)
+ sym = sym_evaudio;
+ else if(ev.type == kVstVideoType)
+ sym = sym_evvideo;
+ else if(ev.type == kVstParameterType)
+ sym = sym_evparam;
+ else if(ev.type == kVstTriggerType)
+ sym = sym_evtrigger;
+ else if(ev.type == kVstSysExType)
+ sym = sym_evsysex;
+ else
+ sym = sym_ev_;
+
+ int data = ev.byteSize-sizeof(ev.deltaFrames)-sizeof(ev.flags);
+ const int stsize = 16;
+ t_atom stlst[stsize];
+ t_atom *lst = data+3 > stsize?new t_atom[data+3]:stlst;
+
+ SetSymbol(lst[0],sym);
+ SetInt(lst[1],ev.deltaFrames);
+ SetInt(lst[2],ev.flags);
+ for(int i = 0; i < data; ++i) SetInt(lst[3],(unsigned char)ev.data[i]);
+
+ responder->Respond(sym_event,data+3,lst);
+
+ if(lst != stlst) delete[] lst;
+ }
+}
+
+// Host callback dispatcher
+long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+{
+#ifdef FLEXT_LOGGING
+ 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
+
+ VSTPlugin *th = effect?(VSTPlugin *)effect->user:NULL;
+
+ switch (opcode) {
+ case audioMasterAutomate: // 0
+#ifdef FLEXT_LOGGING
+ 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;
+
+ case audioMasterCurrentId: // 2
+ // set to subplugin id (default 0)
+ return uniqueid;
+
+ 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_LOGGING
+ post("Pin connected pin=%li conn=%li",index,value);
+#endif
+ return 0; // 0 means connected
+
+ case audioMasterWantMidi: // 6
+#ifdef FLEXT_LOGGING
+ post("Want MIDI = %li",value);
+#endif
+ return 0; // VST header says: "currently ignored"
+
+ case audioMasterGetTime: { // 7
+ if(!th) return 0;
+
+ static VstTimeInfo time;
+ memset(&time,0,sizeof(time));
+
+ // flags
+ time.flags = kVstTempoValid|kVstBarsValid|kVstCyclePosValid|kVstPpqPosValid|kVstSmpteValid|kVstTimeSigValid;
+
+ if(th->transchg) { time.flags |= kVstTransportChanged; th->transchg = false; }
+ if(th->playing) time.flags |= kVstTransportPlaying;
+ if(th->looping) time.flags |= kVstTransportCycleActive;
+
+ time.sampleRate = th->samplerate;
+ time.samplePos = th->samplepos;
+ time.ppqPos = th->ppqpos;
+
+ time.tempo = th->tempo;
+ time.barStartPos = th->barstartpos;
+ time.cycleStartPos = th->cyclestartpos;
+ time.cycleEndPos = th->cycleendpos;
+
+ time.timeSigNumerator = th->timesignom;
+ time.timeSigDenominator = th->timesigden;
+
+ // SMPTE data
+ time.smpteOffset = th->smpteoffset;
+ time.smpteFrameRate = th->smpterate;
+
+// time.samplesToNextClock = 0;
+
+ if(value&kVstNanosValid) {
+ time.nanoSeconds = flext::GetOSTime()*1.e9;
+ time.flags |= kVstNanosValid;
+ }
+
+ return (long)&time;
+ }
+
+ case audioMasterProcessEvents: { // 8
+ // VST event data from plugin
+ VstEvents *evs = static_cast<VstEvents *>(ptr);
+ if(th) {
+ for(int i = 0; i < evs->numEvents; ++i)
+ th->ProcessEvent(*evs->events[i]);
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ 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
+ return 0; // not supported
+ case audioMasterGetBlockSize: // 17
+ return 0; // not supported
+
+ case audioMasterGetCurrentProcessLevel: // 23
+ // return thread state
+ return flext::GetThreadId() == flext::GetSysThreadId()?2:1;
+
+ case audioMasterGetVendorString: // 32
+ strcpy((char*)ptr,vendor);
+ return 0;
+
+ case audioMasterGetProductString: // 33
+ strcpy((char *)ptr,product);
+ return 0;
+
+ case audioMasterGetVendorVersion: // 34
+ return VST_VERSION;
+
+ case audioMasterCanDo: // 37
+#ifdef FLEXT_LOGGING
+ 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; // deprecated - new one is shellCategory
+ else if(!strcmp((char *)ptr,"offline"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"asyncProcessing"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"shellCategory"))
+ return 1; // supported!
+ else if(!strcmp((char *)ptr,"editFile"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"openFileSelector"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"closeFileSelector"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"startStopProcess"))
+ return 0; // not supported
+#ifdef FLEXT_DEBUG
+ else
+ post("Unknown audioMasterCanDo PTR = %s",ptr);
+#endif
+
+ return 0; // not supported
+
+ case audioMasterGetLanguage: // 38
+ return kVstLangEnglish;
+
+ case audioMasterGetDirectory: // 41
+ return (long)(th?th->dllname.c_str():dllloading.c_str());
+
+ case audioMasterUpdateDisplay: // 42
+#ifdef FLEXT_LOGGING
+ post("UPDATE DISPLAY");
+#endif
+ return 0;
+
+ default:
+#ifdef FLEXT_DEBUG
+ post("Unknown opcode %li",opcode);
+#endif
+ return 0;
+ }
+}
+
+void VSTPlugin::updatepos(long frames)
+{
+ bool inloop = ppqpos < cycleendpos;
+
+ // \todo should the sample position also jump back when cycling?
+ // and if, how?
+ samplepos += frames;
+
+ ppqpos += frames*tempo/(samplerate*60);
+
+ if(looping) {
+ double cyclelen = cycleendpos-cyclestartpos;
+ if(cyclelen > 0) {
+ if(inloop && ppqpos >= cycleendpos)
+ ppqpos = cyclestartpos+fmod(ppqpos-cyclestartpos,cyclelen);
+ }
+ else
+ ppqpos = cyclestartpos;
+ }
+}