//------------------------------------------------------------------------------------------------------- // VST Plug-Ins SDK // Version 2.3 Extension // © 2003 Steinberg Media Technologies, All Rights Reserved // // you should not have to edit this file // use override methods instead, as suggested in the class declaration (audioeffectx.h) //------------------------------------------------------------------------------------------------------- #ifndef __audioeffectx__ #include "AudioEffectX.hpp" #endif #ifndef __AEffEditor__ #include "AEffEditor.hpp" #endif //--------------------------------------------------------------------------------------------- // 'canDo' strings. note other 'canDos' can be evaluated by calling the according // function, for instance if getSampleRate returns 0, you // will certainly want to assume that this selector is not supported. //--------------------------------------------------------------------------------------------- const char* hostCanDos [] = { "sendVstEvents", "sendVstMidiEvent", "sendVstTimeInfo", "receiveVstEvents", "receiveVstMidiEvent", "receiveVstTimeInfo", "reportConnectionChanges", "acceptIOChanges", "sizeWindow", "asyncProcessing", "offline", "supplyIdle", "supportShell", // old waveshell handling, dont use it anymore. "openFileSelector" #if VST_2_2_EXTENSIONS , "editFile", "closeFileSelector" #endif // VST_2_2_EXTENSIONS #if VST_2_3_EXTENSIONS , "startStopProcess", // if supported by the Host, it will call startProcess and stopProcess "shellCategory" // 'shell' handling via uniqueID. If supported by the Host and // the Plugin has the category kPlugCategShell the host will call // getNextShellPlugin () to extract the name of each included plugin. #endif // VST_2_3_EXTENSIONS }; const char* plugCanDos [] = { "sendVstEvents", "sendVstMidiEvent", "sendVstTimeInfo", "receiveVstEvents", "receiveVstMidiEvent", "receiveVstTimeInfo", "offline", "plugAsChannelInsert", "plugAsSend", "mixDryWet", "noRealTime", "multipass", "metapass", "1in1out", "1in2out", "2in1out", "2in2out", "2in4out", "4in2out", "4in4out", "4in8out", // 4:2 matrix to surround bus "8in4out", // surround bus to 4:2 matrix "8in8out" #if VST_2_1_EXTENSIONS , "midiProgramNames", "conformsToWindowRules" // mac: doesn't mess with grafport. general: may want // to call sizeWindow (). if you want to use sizeWindow (), // you must return true (1) in canDo ("conformsToWindowRules") #endif // VST_2_1_EXTENSIONS #if VST_2_3_EXTENSIONS , "bypass" #endif // VST_2_3_EXTENSIONS }; //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- // AudioEffectX extends AudioEffect with the new features. so you should derive // your plug from AudioEffectX //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- // VstEvents + VstTimeInfo //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- AudioEffectX::AudioEffectX (AudioMasterCallback audioMaster, long numPrograms, long numParams) : AudioEffect (audioMaster, numPrograms, numParams) { } //------------------------------------------------------------------------------------------------------- AudioEffectX::~AudioEffectX () { } //------------------------------------------------------------------------------------------------------- long AudioEffectX::dispatcher (long opCode, long index, long value, void *ptr, float opt) { long v = 0; switch(opCode) { // VstEvents case effProcessEvents: v = processEvents ((VstEvents*)ptr); break; // parameters and programs case effCanBeAutomated: v = canParameterBeAutomated (index) ? 1 : 0; break; case effString2Parameter: v = string2parameter (index, (char*)ptr) ? 1 : 0; break; case effGetNumProgramCategories: v = getNumCategories (); break; case effGetProgramNameIndexed: v = getProgramNameIndexed (value, index, (char*)ptr) ? 1 : 0; break; case effCopyProgram: v = copyProgram (index) ? 1 : 0; break; // connections, configuration case effConnectInput: inputConnected (index, value ? true : false); v = 1; break; case effConnectOutput: outputConnected (index, value ? true : false); v = 1; break; case effGetInputProperties: v = getInputProperties (index, (VstPinProperties*)ptr) ? 1 : 0; break; case effGetOutputProperties: v = getOutputProperties (index, (VstPinProperties*)ptr) ? 1 : 0; break; case effGetPlugCategory: v = (long)getPlugCategory (); break; // realtime case effGetCurrentPosition: v = reportCurrentPosition (); break; case effGetDestinationBuffer: v = (long)reportDestinationBuffer (); break; // offline case effOfflineNotify: v = offlineNotify ((VstAudioFile*)ptr, value, index != 0); break; case effOfflinePrepare: v = offlinePrepare ((VstOfflineTask*)ptr, value); break; case effOfflineRun: v = offlineRun ((VstOfflineTask*)ptr, value); break; // other case effSetSpeakerArrangement: v = setSpeakerArrangement ((VstSpeakerArrangement*)value, (VstSpeakerArrangement*)ptr) ? 1 : 0; break; case effProcessVarIo: v = processVariableIo ((VstVariableIo*)ptr) ? 1 : 0; break; case effSetBlockSizeAndSampleRate: setBlockSizeAndSampleRate (value, opt); v = 1; break; case effSetBypass: v = setBypass (value ? true : false) ? 1 : 0; break; case effGetEffectName: v = getEffectName ((char *)ptr) ? 1 : 0; break; case effGetErrorText: v = getErrorText ((char *)ptr) ? 1 : 0; break; case effGetVendorString: v = getVendorString ((char *)ptr) ? 1 : 0; break; case effGetProductString: v = getProductString ((char *)ptr) ? 1 : 0; break; case effGetVendorVersion: v = getVendorVersion (); break; case effVendorSpecific: v = vendorSpecific (index, value, ptr, opt); break; case effCanDo: v = canDo ((char*)ptr); break; case effGetIcon: v = (long)getIcon (); break; case effSetViewPosition: v = setViewPosition (index, value) ? 1 : 0; break; case effGetTailSize: v = getGetTailSize (); break; case effIdle: v = fxIdle (); break; case effGetParameterProperties: v = getParameterProperties (index, (VstParameterProperties*)ptr) ? 1 : 0; break; case effKeysRequired: v = (keysRequired () ? 0 : 1); // reversed to keep v1 compatibility break; case effGetVstVersion: v = getVstVersion (); break; #if VST_2_1_EXTENSIONS case effEditKeyDown: if (editor) { VstKeyCode keyCode = {index, (unsigned char)value, (unsigned char)opt}; v = editor->onKeyDown (keyCode); } break; case effEditKeyUp: if (editor) { VstKeyCode keyCode = {index, (unsigned char)value, (unsigned char)opt}; v = editor->onKeyUp (keyCode); } break; case effSetEditKnobMode: if (editor) v = editor->setKnobMode (value); break; case effGetMidiProgramName: v = getMidiProgramName (index, (MidiProgramName*)ptr); break; case effGetCurrentMidiProgram: v = getCurrentMidiProgram (index, (MidiProgramName*)ptr); break; case effGetMidiProgramCategory: v = getMidiProgramCategory (index, (MidiProgramCategory*)ptr); break; case effHasMidiProgramsChanged: v = hasMidiProgramsChanged (index) ? 1 : 0; break; case effGetMidiKeyName: v = getMidiKeyName (index, (MidiKeyName*)ptr) ? 1 : 0; break; case effBeginSetProgram: v = beginSetProgram () ? 1 : 0; break; case effEndSetProgram: v = endSetProgram () ? 1 : 0; break; #endif // VST_2_1_EXTENSIONS #if VST_2_3_EXTENSIONS case effGetSpeakerArrangement: v = getSpeakerArrangement ((VstSpeakerArrangement**)value, (VstSpeakerArrangement**)ptr) ? 1 : 0; break; case effSetTotalSampleToProcess: v = setTotalSampleToProcess (value); break; case effShellGetNextPlugin: v = getNextShellPlugin ((char*)ptr); break; case effStartProcess: v = startProcess (); break; case effStopProcess: v = stopProcess (); break; case effSetPanLaw: v = setPanLaw (value, opt) ? 1 : 0; break; case effBeginLoadBank: v = beginLoadBank ((VstPatchChunkInfo*)ptr); break; case effBeginLoadProgram: v = beginLoadProgram ((VstPatchChunkInfo*)ptr); break; #endif // VST_2_3_EXTENSIONS // version 1.0 or unknown default: v = AudioEffect::dispatcher (opCode, index, value, ptr, opt); } return v; } //------------------------------------------------------------------------------------------------------- void AudioEffectX::wantEvents (long filter) { if (audioMaster) audioMaster (&cEffect, audioMasterWantMidi, 0, filter, 0, 0); } //------------------------------------------------------------------------------------------------------- VstTimeInfo* AudioEffectX::getTimeInfo (long filter) { if (audioMaster) return (VstTimeInfo*) audioMaster (&cEffect, audioMasterGetTime, 0, filter, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::tempoAt (long pos) { if (audioMaster) return audioMaster (&cEffect, audioMasterTempoAt, 0, pos, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::sendVstEventsToHost (VstEvents* events) { if (audioMaster) return audioMaster (&cEffect, audioMasterProcessEvents, 0, 0, events, 0) == 1; return 0; } //------------------------------------------------------------------------------------------------------- // Parameters //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- long AudioEffectX::getNumAutomatableParameters () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetNumAutomatableParameters, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getParameterQuantization () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetParameterQuantization, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- // Configuration //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- bool AudioEffectX::ioChanged () { if (audioMaster) return (audioMaster (&cEffect, audioMasterIOChanged, 0, 0, 0, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::needIdle () { if (audioMaster) return (audioMaster (&cEffect, audioMasterNeedIdle, 0, 0, 0, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::sizeWindow (long width, long height) { if (audioMaster) return (audioMaster (&cEffect, audioMasterSizeWindow, width, height, 0, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- double AudioEffectX::updateSampleRate () { if (audioMaster) { long res = audioMaster (&cEffect, audioMasterGetSampleRate, 0, 0, 0, 0); if (res > 0) sampleRate = (float)res; } return sampleRate; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::updateBlockSize () { if (audioMaster) { long res = audioMaster (&cEffect, audioMasterGetBlockSize, 0, 0, 0, 0); if (res > 0) blockSize = res; } return blockSize; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getInputLatency () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetInputLatency, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getOutputLatency () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetOutputLatency, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- AEffect* AudioEffectX::getPreviousPlug (long input) { if (audioMaster) return (AEffect*) audioMaster (&cEffect, audioMasterGetPreviousPlug, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- AEffect* AudioEffectX::getNextPlug (long output) { if (audioMaster) return (AEffect*) audioMaster (&cEffect, audioMasterGetNextPlug, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- // Configuration //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- long AudioEffectX::willProcessReplacing () { if (audioMaster) return audioMaster (&cEffect, audioMasterWillReplaceOrAccumulate, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getCurrentProcessLevel () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetCurrentProcessLevel, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getAutomationState () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetAutomationState, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- void AudioEffectX::wantAsyncOperation (bool state) { if (state) cEffect.flags |= effFlagsExtIsAsync; else cEffect.flags &= ~effFlagsExtIsAsync; } //------------------------------------------------------------------------------------------------------- void AudioEffectX::hasExternalBuffer (bool state) { if (state) cEffect.flags |= effFlagsExtHasBuffer; else cEffect.flags &= ~effFlagsExtHasBuffer; } //------------------------------------------------------------------------------------------------------- // Offline //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- bool AudioEffectX::offlineRead (VstOfflineTask* offline, VstOfflineOption option, bool readSource) { if (audioMaster) return (audioMaster (&cEffect, audioMasterOfflineRead, readSource, option, offline, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::offlineWrite (VstOfflineTask* offline, VstOfflineOption option) { if (audioMaster) return (audioMaster (&cEffect, audioMasterOfflineWrite, 0, option, offline, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::offlineStart (VstAudioFile* audioFiles, long numAudioFiles, long numNewAudioFiles) { if (audioMaster) return (audioMaster (&cEffect, audioMasterOfflineStart, numNewAudioFiles, numAudioFiles, audioFiles, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::offlineGetCurrentPass () { if (audioMaster) return (audioMaster (&cEffect, audioMasterOfflineGetCurrentPass, 0, 0, 0, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::offlineGetCurrentMetaPass () { if (audioMaster) return (audioMaster (&cEffect, audioMasterOfflineGetCurrentMetaPass, 0, 0, 0, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- // Other //------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------- void AudioEffectX::setOutputSamplerate (float sampleRate) { if (audioMaster) audioMaster (&cEffect, audioMasterSetOutputSampleRate, 0, 0, 0, sampleRate); } //------------------------------------------------------------------------------------------------------- VstSpeakerArrangement* AudioEffectX::getInputSpeakerArrangement () { if (audioMaster) return (VstSpeakerArrangement*)audioMaster (&cEffect, audioMasterGetInputSpeakerArrangement, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- VstSpeakerArrangement* AudioEffectX::getOutputSpeakerArrangement () { if (audioMaster) return (VstSpeakerArrangement*)audioMaster (&cEffect, audioMasterGetOutputSpeakerArrangement, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::getHostVendorString (char* text) { if (audioMaster) return (audioMaster (&cEffect, audioMasterGetVendorString, 0, 0, text, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::getHostProductString (char* text) { if (audioMaster) return (audioMaster (&cEffect, audioMasterGetProductString, 0, 0, text, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getHostVendorVersion () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetVendorVersion, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::hostVendorSpecific (long lArg1, long lArg2, void* ptrArg, float floatArg) { if (audioMaster) return audioMaster (&cEffect, audioMasterVendorSpecific, lArg1, lArg2, ptrArg, floatArg); return 0; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::canHostDo (char* text) { if (audioMaster) return (audioMaster (&cEffect, audioMasterCanDo, 0, 0, text, 0) != 0); return 0; } //------------------------------------------------------------------------------------------------------- void AudioEffectX::isSynth (bool state) { if (state) cEffect.flags |= effFlagsIsSynth; else cEffect.flags &= ~effFlagsIsSynth; } //------------------------------------------------------------------------------------------------------- void AudioEffectX::noTail (bool state) { if (state) cEffect.flags |= effFlagsNoSoundInStop; else cEffect.flags &= ~effFlagsNoSoundInStop; } //------------------------------------------------------------------------------------------------------- long AudioEffectX::getHostLanguage () { if (audioMaster) return audioMaster (&cEffect, audioMasterGetLanguage, 0, 0, 0, 0); return 0; } //------------------------------------------------------------------------------------------------------- void* AudioEffectX::openWindow (VstWindow* window) { if (audioMaster) return (void*)audioMaster (&cEffect, audioMasterOpenWindow, 0, 0, window, 0); return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::closeWindow (VstWindow* window) { if (audioMaster) return (audioMaster (&cEffect, audioMasterCloseWindow, 0, 0, window, 0) != 0); return false; } //------------------------------------------------------------------------------------------------------- void* AudioEffectX::getDirectory () { if (audioMaster) return (void*)(audioMaster (&cEffect, audioMasterGetDirectory, 0, 0, 0, 0)); return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::updateDisplay () { if (audioMaster) return (audioMaster (&cEffect, audioMasterUpdateDisplay, 0, 0, 0, 0)) ? true : false; return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::beginEdit (long index) { if (audioMaster) return (audioMaster (&cEffect, audioMasterBeginEdit, index, 0, 0, 0)) ? true : false; return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::endEdit (long index) { if (audioMaster) return (audioMaster (&cEffect, audioMasterEndEdit, index, 0, 0, 0)) ? true : false; return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::openFileSelector (VstFileSelect* ptr) { if (audioMaster && ptr) return (audioMaster (&cEffect, audioMasterOpenFileSelector, 0, 0, ptr, 0)) ? true : false; return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::closeFileSelector (VstFileSelect* ptr) { if (audioMaster && ptr) return (audioMaster (&cEffect, audioMasterCloseFileSelector, 0, 0, ptr, 0)) ? true : false; return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::getChunkFile (void* nativePath) { if (audioMaster && nativePath) return (audioMaster (&cEffect, audioMasterGetChunkFile, 0, 0, nativePath, 0)) ? true : false; return 0; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::allocateArrangement (VstSpeakerArrangement** arrangement, long nbChannels) { if (*arrangement) { char *ptr = (char*)(*arrangement); delete []ptr; } long size = sizeof (long) + sizeof (long) + (nbChannels) * sizeof (VstSpeakerProperties); char *ptr = new char [size]; if (!ptr) return false; memset (ptr, 0, size); *arrangement = (VstSpeakerArrangement*)ptr; (*arrangement)->numChannels = nbChannels; return true; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::deallocateArrangement (VstSpeakerArrangement** arrangement) { if (*arrangement) { char *ptr = (char*)(*arrangement); delete []ptr; *arrangement = 0; } return true; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::copySpeaker (VstSpeakerProperties* to, VstSpeakerProperties* from) { // We assume here that "to" exists yet, ie this function won't // allocate memory for the speaker (this will prevent from having // a difference between an Arrangement's number of channels and // its actual speakers...) if ((from == NULL) || (to == NULL)) return false; strcpy (to->name, from->name); to->type = from->type; to->azimuth = from->azimuth; to->elevation = from->elevation; to->radius = from->radius; to->reserved = from->reserved; memcpy (to->future, from->future, 28); return true; } //------------------------------------------------------------------------------------------------------- bool AudioEffectX::matchArrangement (VstSpeakerArrangement** to, VstSpeakerArrangement* from) { if (from == NULL) return false; if ((!deallocateArrangement (to)) || (!allocateArrangement (to, from->numChannels))) return false; (*to)->type = from->type; for (int i = 0; i < (*to)->numChannels; i++) { if (!copySpeaker (&((*to)->speakers[i]), &(from->speakers[i]))) return false; } return true; } //------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------