I wrote a small example that works on Windows x86 / x64. I only tested at Cockos Reaper, in other DAWs it should work just as well.
Thanks a lot for helping Infratec and fixing my a few bugs with pointers.
Code: Select all
; file AEffect.pbi
; VST SDK (version 2.4) for PureBasic
; tested only os Windows x86 / x64
; Alex Longard 20.02.2019
; Steinberg Media Technologies GmbH, All Rights Reserved
#kVstVersion = 2400
#kEffectMagic = $56737450
; prototypes for function pointers
PrototypeC.i AudioMasterCallback(*effect, opcode.l, index.l, Value.i, *ptr, opt.f)
PrototypeC.i DispatcherProc(*effect, opcode.l, index.l, Value.i, *ptr, opt.f)
PrototypeC ProcessProc(*effect, *inputs.Float, *outputs.Float, sampleframes.l)
PrototypeC SetParameterProc(*effect, index.l, parameter.f)
PrototypeC.f GetParameterProc(*effect, index.l)
PrototypeC ProcessReplacingProc(*effect, *inputs.Float, *outputs.Float, sampleframes.l)
PrototypeC ProcessDoubleReplacingProc(*effect, *inputs.Double, *outputs.Double, sampleframes.l)
; Basic VST Effect "C" Interface.
Structure AEffect Align #PB_Structure_AlignC
magic.l ; must be #kEffectMagic ('VstP')
dispatcher.DispatcherProc ; Host to Plug-in dispatcher
process.ProcessProc ; \deprecated Accumulating process mode is deprecated in VST 2.4! Use AEffect::processReplacing instead!
setParameter.SetParameterProc ; Set new value of automatable parameter
getParameter.GetParameterProc ; Returns current value of automatable parameter
numPrograms.l ; number of programs
numParams.l ; all programs are assumed to have numParams parameters
numInputs.l ; number of audio inputs
numOutputs.l ; number of audio outputs
flags.l ; @see VstAEffectFlags
*resvd1 ; reserved for Host, must be 0
*resvd2 ; reserved for Host, must be 0
initialDelay.l ; for algorithms which need input in the first place (Group delay or latency in Samples). This value should be initialized in a resume state.
realQualities.l ; \deprecated unused member
offQualities.l ; \deprecated unused member
ioRatio.f ; \deprecated unused member
*Object ; #AudioEffect class pointer (for PB must be 0)
*user ; user defined pointer
uniqueID.l ; registered unique identifier (register it at Steinberg 3rd party support Web). This is used to identify a plug-in during save+load of preset and project.
version.l ; plug-in version (example 1100 for version 1.1.0.0)
processReplacing.ProcessReplacingProc ; Process audio samples in replacing mode
processDoubleReplacing.ProcessDoubleReplacingProc ; Process double-precision audio samples in replacing mode
Array future.b(56) ; reserved for future use (please zero)
EndStructure
; AEffect flags
#effFlagsHasEditor = 1 ; set If the plug-in provides a custom editor
#effFlagsCanReplacing = 16 ; supports replacing process mode (which should the Default mode in VST 2.4)
#effFlagsProgramChunks = 32 ; program Data is handled in formatless chunks
#effFlagsIsSynth = 256 ; plug-in is a synth (VSTi), Host may assign mixer channels For its outputs
#effFlagsNoSoundInStop = 512 ; plug-in does Not produce sound when input is all silence
#effFlagsCanDoubleReplacing = 4096 ; plug-in supports double precision processing
#effFlagsHasClip = 2 ; deprecated in VST 2.4
#effFlagsHasVu = 4 ; deprecated in VST 2.4
#effFlagsCanMono = 16 ; deprecated in VST 2.4
#effFlagsExtIsAsync = 1024 ; deprecated in VST 2.4
#effFlagsExtHasBuffer = 2048 ; deprecated in VST 2.4
; Basic dispatcher Opcodes (Host To Plug-in) */
#effOpen = 0 ; no arguments
#effClose = 1 ; no arguments
#effSetProgram = 2 ; [value]: new program number
#effGetProgram = 3 ; [Return value]: current program number
#effSetProgramName = 4 ; [ptr]: char* With new program name, limited To #kVstMaxProgNameLen
#effGetProgramName = 5 ; [ptr]: char buffer For current program name, limited To #kVstMaxProgNameLen
#effGetParamLabel = 6 ; [ptr]: char buffer For parameter label, limited To #kVstMaxParamStrLen
#effGetParamDisplay = 7; [ptr]: char buffer For parameter display, limited To #kVstMaxParamStrLen
#effGetParamName = 8 ; [ptr]: char buffer For parameter name, limited To #kVstMaxParamStrLen
#effGetVu = 9 ; deprecated in VST 2.4
#effSetSampleRate = 10 ; [opt]: new sample rate For audio processing
#effSetBlockSize = 11 ; [value]: new maximum block size For audio processing
#effMainsChanged = 12 ; [value]: 0 means "turn off", 1 means "turn on" @see AudioEffect::suspend @see AudioEffect::resume
#effEditGetRect = 13 ; [ptr]: #ERect** receiving pointer To editor size
#effEditOpen = 14 ; [ptr]: system dependent Window pointer, e.g. HWND on Windows @see AEffEditor::open
#effEditClose = 15 ; no arguments
#effEditDraw = 16 ; deprecated in VST 2.4
#effEditMouse = 17 ; deprecated in VST 2.4
#effEditKey = 18 ; deprecated in VST 2.4
#effEditIdle = 19 ; no arguments
#effEditTop = 20 ; deprecated in VST 2.4
#effEditSleep = 21 ; deprecated in VST 2.4
#effIdentify = 22 ; deprecated in VST 2.4
#effGetChunk = 23 ; [ptr]: void** For chunk Data address [index]: 0 For bank, 1 For program
#effSetChunk = 24 ; [ptr]: chunk Data [value]: byte size [index]: 0 For bank, 1 For program
#effNumOpcodes = 25
; Basic dispatcher Opcodes (Plug-in To Host)
#audioMasterAutomate = 0 ; [index]: parameter index [opt]: parameter value
#audioMasterVersion = 1 ; [Return value]: Host VST version (For example 2400 For VST 2.4)
#audioMasterCurrentId = 2 ; [Return value]: current unique identifier on shell plug-in
#audioMasterIdle = 3 ; no arguments
#audioMasterPinConnected = 4 ; deprecated in VST 2.4 r2
; String length limits (in characters excl. 0 byte)
#kVstMaxProgNameLen = 24 ; used For #effGetProgramName, #effSetProgramName, #effGetProgramNameIndexed
#kVstMaxParamStrLen = 12 ; used For #effGetParamLabel, #effGetParamDisplay, #effGetParamName
#kVstMaxVendorStrLen = 64 ; used For #effGetVendorString, #audioMasterGetVendorString
#kVstMaxProductStrLen = 64 ; used For #effGetProductString, #audioMasterGetProductString
#kVstMaxEffectNameLen = 32 ; used For #effGetEffectName
; Structure used For #effEditGetRect.
Structure ERect Align #PB_Structure_AlignC
top.l ; top coordinate
left.l ; left coordinate
bottom.l ; bottom coordinate
right.l ; right coordinate
EndStructure
Code: Select all
; file AEffectX.pbi
; VST SDK (version 2.4) for PureBasic
; tested only os Windows x86 / x64
; Alex Longard 20.08.2020
; Steinberg Media Technologies GmbH, All Rights Reserved
XIncludeFile "aeffect.pbi"
; String length limits (in characters excl. 0 byte).
; Vst2StringConstants
#kVstMaxNameLen = 64 ; used For #MidiProgramName, #MidiProgramCategory, #MidiKeyName, #VstSpeakerProperties, #VstPinProperties
#kVstMaxLabelLen = 64 ; used For #VstParameterProperties->label, #VstPinProperties->label
#kVstMaxShortLabelLen = 8 ; used For #VstParameterProperties->shortLabel, #VstPinProperties->shortLabel
#kVstMaxCategLabelLen = 24 ; used For #VstParameterProperties->label
#kVstMaxFileNameLen = 100 ; used For #VstAudioFile->name
; VstEvent
; A generic timestamped event.
Structure VstEvent Align #PB_Structure_AlignC
type.l ; @see VstEventTypes
byteSize.l ; size of this event, excl. type and byteSize
deltaFrames.l ; sample frames related to the current block start sample position
flags.l ; generic flags, none defined yet
Array Data.b(15) ; data size may vary, depending on event type
EndStructure
; VstEvent Types used by #VstEvent.
#kVstMidiType = 1 ; MIDI event @see VstMidiEvent
#kVstAudioType = 2 ; deprecated unused event type
#kVstVideoType = 3 ; deprecated unused event type
#kVstParameterType = 4 ; deprecated unused event type
#kVstTriggerType = 5 ; deprecated unused event type
#kVstSysExType = 6 ; MIDI system exclusive @see VstMidiSysexEvent
; A block of events For the current processed audio block.
Structure VstEvents Align #PB_Structure_AlignC
numEvents.l ; number of Events in array
*reserved ; zero (Reserved for future use)
*events.VstEvent[1] ; event pointer array, variable size
EndStructure
; MIDI Event (To be casted from VstEvent).
Structure VstMidiEvent Align #PB_Structure_AlignC
type.l ; #kVstMidiType
byteSize.l ; sizeof (VstMidiEvent)
deltaFrames.l ; sample frames related To the current block start sample position
flags.l ; @see VstMidiEventFlags
noteLength.l ; (in sample frames) of entire note, if available, else 0
noteOffset.l ; offset (in sample frames) into note from note start if available, else 0
midiData.b[4] ; 1 to 3 MIDI bytes; midiData[3] is reserved (zero)
detune.c ; -64 to +63 cents; for scales other than 'well-tempered' ('microtuning')
noteOffVelocity.b ; Note Off Velocity [0, 127]
reserved1.b ; zero (Reserved for future use)
reserved2.b ; zero (Reserved for future use)
EndStructure
; Flags used in #VstMidiEvent.
; VstMidiEventFlags
#kVstMidiEventIsRealtime = 1 ; means that this event is played life (Not in playback from a sequencer track).\n This allows the Plug-In To handle these flagged events With higher priority, especially when the Plug-In has a big latency (AEffect::initialDelay)
; MIDI Sysex Event (To be casted from #VstEvent).
Structure VstMidiSysexEvent Align #PB_Structure_AlignC
type.l ; #kVstSysexType
byteSize.l ; sizeof (VstMidiSysexEvent)
deltaFrames.l ; sample frames related to the current block start sample position
flags.l ; none defined yet (should be zero)
dumpBytes.l ; byte size of sysexDump
*resvd1 ; zero (Reserved for future use)
sysexDump.b ; sysex dump
*resvd2 ; zero (Reserved for future use)
EndStructure
; VstTimeInfo requested via #audioMasterGetTime. @see AudioEffectX::getTimeInfo
; note VstTimeInfo::samplePos :Current Position. It must always be valid, And should Not cost a lot To ask For. The sample position is ahead of the time displayed To the user. In sequencer stop mode, its value does Not change. A 32 bit integer is too small For sample positions, And it's a double to make it easier to convert between ppq and samples.
; note VstTimeInfo::ppqPos : At tempo 120, 1 quarter makes 1/2 second, so 2.0 ppq translates To 48000 samples at 48kHz sample rate.
; .25 ppq is one sixteenth note then. If you need something like 480ppq, you simply multiply ppq by that scaler.
; note VstTimeInfo::barStartPos : Say we're at bars/beats readout 3.3.3. That's 2 bars + 2 q + 2 sixteenth, makes 2 * 4 + 2 + .25 = 10.25 ppq. at tempo 120, that's 10.25 * .5 = 5.125 seconds, times 48000 = 246000 samples (if my calculator servers me well :-).
; note VstTimeInfo::samplesToNextClock : MIDI Clock Resolution (24 per Quarter Note), can be negative the distance To the Next midi clock (24 ppq, pulses per quarter) in samples. unless samplePos falls precicely on a midi clock, this will either be negative such that the previous MIDI clock is addressed, Or positive when referencing the following (future) MIDI clock.
Structure VstTimeInfo Align #PB_Structure_AlignC
samplePos.d ; current Position in audio samples (always valid)
sampleRate.d ; current Sample Rate in Herz (always valid)
nanoSeconds.d ; System Time in nanoseconds (10^-9 second)
ppqPos.d ; Musical Position, in Quarter Note (1.0 equals 1 Quarter Note)
tempo.d ; current Tempo in BPM (Beats Per Minute)
barStartPos.d ; last Bar Start Position, in Quarter Note
cycleStartPos.d ; Cycle Start (left locator), in Quarter Note
cycleEndPos.d ; Cycle End (right locator), in Quarter Note
timeSigNumerator.l ; Time Signature Numerator (e.g. 3 for 3/4)
timeSigDenominator.l ; Time Signature Denominator (e.g. 4 for 3/4)
smpteOffset.l ; SMPTE offset (in SMPTE subframes (bits; 1/80 of a frame)). The current SMPTE position can be calculated using #samplePos, #sampleRate, and #smpteFrameRate.
smpteFrameRate.l ; @see VstSmpteFrameRate
samplesToNextClock.l ; MIDI Clock Resolution (24 Per Quarter Note), can be negative (nearest clock)
flags.l ; @see VstTimeInfoFlags
EndStructure
; Flags used in #VstTimeInfo.
#kVstTransportChanged = 1 ; indicates that play, cycle Or record state has changed
#kVstTransportPlaying = 2 ; set If Host sequencer is currently playing
#kVstTransportCycleActive = 4 ; set If Host sequencer is in cycle mode
#kVstTransportRecording = 8 ; set If Host sequencer is in record mode
#kVstAutomationWriting = 64 ; set If automation write mode active (record parameter changes)
#kVstAutomationReading = 128 ; set If automation Read mode active (play parameter changes)
#kVstNanosValid = 256 ; VstTimeInfo::nanoSeconds valid
#kVstPpqPosValid = 512 ; VstTimeInfo::ppqPos valid
#kVstTempoValid = 1024 ; VstTimeInfo::tempo valid
#kVstBarsValid = 2048 ; VstTimeInfo::barStartPos valid
#kVstCyclePosValid = 4096 ; VstTimeInfo::cycleStartPos And VstTimeInfo::cycleEndPos valid
#kVstTimeSigValid = 8192 ; VstTimeInfo::timeSigNumerator And VstTimeInfo::timeSigDenominator valid
#kVstSmpteValid = 16384 ; VstTimeInfo::smpteOffset And VstTimeInfo::smpteFrameRate valid
#kVstClockValid = 32768 ; VstTimeInfo::samplesToNextClock valid
; SMPTE Frame Rates.
#kVstSmpte24fps = 0 ; 24 fps
#kVstSmpte25fps = 1 ; 25 fps
#kVstSmpte2997fps = 2 ; 29.97 fps
#kVstSmpte30fps = 3 ; 30 fps
#kVstSmpte2997dfps = 4 ; 29.97 drop
#kVstSmpte30dfps = 5 ; 30 drop
#kVstSmpteFilm16mm = 6 ; Film 16mm
#kVstSmpteFilm35mm = 7 ; Film 35mm
#kVstSmpte239fps = 10 ; HDTV: 23.976 fps
#kVstSmpte249fps = 11 ; HDTV: 24.976 fps
#kVstSmpte599fps = 12 ; HDTV: 59.94 fps
#kVstSmpte60fps = 13 ; HDTV: 60 fps
; Variable IO For Offline Processing.
Structure VstVariableIo Align #PB_Structure_AlignC
*inputs.Float ; input audio buffers
*outputs.Float ; output audio buffers
numSamplesInput.l ; number of incoming samples
numSamplesOutput.l ; number of outgoing samples
*numSamplesInputProcessed.integer ; number of samples actually processed of input
*numSamplesOutputProcessed.integer ; number of samples actually processed of output
EndStructure
; Language code returned by audioMasterGetLanguage.
#kVstLangEnglish = 1 ; English
#kVstLangGerman = 2 ; German
#kVstLangFrench = 3 ; French
#kVstLangItalian = 4 ; Italian
#kVstLangSpanish = 5 ; Spanish
#kVstLangJapanese = 6 ; Japanese
; VST 2.x dispatcher Opcodes (Plug-in To Host). Extension of #AudioMasterOpcodes
; AudioMasterOpcodesX
#audioMasterWantMidi = #audioMasterPinConnected + 2 ; deprecated in VST 2.4
#audioMasterGetTime = 7 ; [Return value]: #VstTimeInfo* Or null If Not supported [value]: request mask @see VstTimeInfoFlags @see AudioEffectX::getTimeInfo
#audioMasterProcessEvents = 8 ; [ptr]: pointer To #VstEvents @see VstEvents @see AudioEffectX::sendVstEventsToHost
#audioMasterSetTime = 9 ; deprecated in VST 2.4
#audioMasterTempoAt = 10 ; deprecated in VST 2.4
#audioMasterGetNumAutomatableParameters = 11 ; deprecated in VST 2.4
#audioMasterGetParameterQuantization = 12 ; deprecated in VST 2.4
#audioMasterIOChanged = 13 ; [Return value]: 1 If supported @see AudioEffectX::ioChanged
#audioMasterNeedIdle = 14 ; deprecated in VST 2.4
#audioMasterSizeWindow = 15 ; [index]: new width [value]: new height [Return value]: 1 If supported @see AudioEffectX::sizeWindow
#audioMasterGetSampleRate = 16 ; [Return value]: current sample rate @see AudioEffectX::updateSampleRate
#audioMasterGetBlockSize = 17 ; [Return value]: current block size @see AudioEffectX::updateBlockSize
#audioMasterGetInputLatency = 18 ; [Return value]: input latency in audio samples @see AudioEffectX::getInputLatency
#audioMasterGetOutputLatency = 19 ; [Return value]: output latency in audio samples @see AudioEffectX::getOutputLatency
#audioMasterGetPreviousPlug = 20 ; deprecated in VST 2.4
#audioMasterGetNextPlug = 21 ; deprecated in VST 2.4
#audioMasterWillReplaceOrAccumulate = 22 ; deprecated in VST 2.4
#audioMasterGetCurrentProcessLevel = 23 ; [Return value]: current process level @see VstProcessLevels
#audioMasterGetAutomationState = 24 ; [Return value]: current automation state @see VstAutomationStates
#audioMasterOfflineStart = 25 ; [index]: numNewAudioFiles [value]: numAudioFiles [ptr]: #VstAudioFile* @see AudioEffectX::offlineStart
#audioMasterOfflineRead = 26 ; [index]: bool readSource [value]: #VstOfflineOption* @see VstOfflineOption [ptr]: #VstOfflineTask* @see VstOfflineTask @see AudioEffectX::offlineRead
#audioMasterOfflineWrite = 27 ; @see audioMasterOfflineRead @see AudioEffectX::offlineRead
#audioMasterOfflineGetCurrentPass = 28 ; @see AudioEffectX::offlineGetCurrentPass
#audioMasterOfflineGetCurrentMetaPass = 29 ; @see AudioEffectX::offlineGetCurrentMetaPass
#audioMasterSetOutputSampleRate = 30 ; deprecated in VST 2.4
#audioMasterGetOutputSpeakerArrangement = 31 ; deprecated in VST 2.4
#audioMasterGetVendorString = 32 ; [ptr]: char buffer For vendor string, limited To #kVstMaxVendorStrLen @see AudioEffectX::getHostVendorString
#audioMasterGetProductString = 33 ; [ptr]: char buffer For vendor string, limited To #kVstMaxProductStrLen @see AudioEffectX::getHostProductString
#audioMasterGetVendorVersion = 34 ; [Return value]: vendor-specific version @see AudioEffectX::getHostVendorVersion
#audioMasterVendorSpecific = 35 ; no definition, vendor specific handling @see AudioEffectX::hostVendorSpecific
#audioMasterSetIcon = 36 ; deprecated in VST 2.4
#audioMasterCanDo = 37 ; [ptr]: "can do" string [Return value]: 1 For supported
#audioMasterGetLanguage = 38 ; [Return value]: language code @see VstHostLanguage
#audioMasterOpenWindow = 39 ; deprecated in VST 2.4
#audioMasterCloseWindow = 40 ; deprecated in VST 2.4
#audioMasterGetDirectory = 41 ; [Return value]: FSSpec on MAC, Else char* @see AudioEffectX::getDirectory
#audioMasterUpdateDisplay = 42 ; no arguments
#audioMasterBeginEdit = 43 ; [index]: parameter index @see AudioEffectX::beginEdit
#audioMasterEndEdit = 44 ; [index]: parameter index @see AudioEffectX::endEdit
#audioMasterOpenFileSelector = 45 ; [ptr]: VstFileSelect* [Return value]: 1 If supported @see AudioEffectX::openFileSelector
#audioMasterCloseFileSelector = 46 ; [ptr]: VstFileSelect* @see AudioEffectX::closeFileSelector
#audioMasterEditFile = 47 ; deprecated in VST 2.4
#audioMasterGetChunkFile = 48 ; deprecated in VST 2.4 [ptr]: char[2048] Or SizeOf (FSSpec) [Return value]: 1 If supported @see AudioEffectX::getChunkFile
#audioMasterGetInputSpeakerArrangement = 49 ; deprecated in VST 2.4
; VST 2.x dispatcher Opcodes (Host To Plug-in). Extension of #AEffectOpcodes
; AEffectXOpcodes
#effProcessEvents = 25 ; [ptr]: #VstEvents*
#effCanBeAutomated = 26 ; [index]: parameter index [Return value]: 1=true, 0=false
#effString2Parameter = 27 ; [index]: parameter index [ptr]: parameter string [Return value]: true For success
#effGetNumProgramCategories = 28 ; deprecated in VST 2.4
#effGetProgramNameIndexed = 29 ; [index]: program index [ptr]: buffer For program name, limited To #kVstMaxProgNameLen [Return value]: true For success
#effCopyProgram = 30 ; deprecated in VST 2.4
#effConnectInput = 31 ; deprecated in VST 2.4
#effConnectOutput = 32 ; deprecated in VST 2.4
#effGetInputProperties = 33 ; [index]: input index [ptr]: #VstPinProperties* [Return value]: 1 If supported
#effGetOutputProperties = 34 ; [index]: output index [ptr]: #VstPinProperties* [Return value]: 1 If supported
#effGetPlugCategory = 35 ; [Return value]: category @see VstPlugCategory
#effGetCurrentPosition = 36 ; deprecated in VST 2.4
#effGetDestinationBuffer = 37 ; deprecated in VST 2.4
#effOfflineNotify = 38 ; [ptr]: #VstAudioFile Array [value]: count [index]: start flag
#effOfflinePrepare = 39 ; [ptr]: #VstOfflineTask Array [value]: count
#effOfflineRun = 40 ; [ptr]: #VstOfflineTask Array [value]: count
#effProcessVarIo = 41 ; [ptr]: #VstVariableIo*
#effSetSpeakerArrangement = 42 ; [value]: input #VstSpeakerArrangement* [ptr]: output #VstSpeakerArrangement*
#effSetBlockSizeAndSampleRate = 43 ; deprecated in VST 2.4
#effSetBypass = 44 ; [value]: 1 = bypass, 0 = no bypass
#effGetEffectName = 45 ; [ptr]: buffer For effect name, limited To #kVstMaxEffectNameLen
#effGetErrorText = 46 ; deprecated in VST 2.4
#effGetVendorString = 47 ; [ptr]: buffer For effect vendor string, limited To #kVstMaxVendorStrLen
#effGetProductString = 48 ; [ptr]: buffer For effect vendor string, limited To #kVstMaxProductStrLen
#effGetVendorVersion = 49 ; [Return value]: vendor-specific version
#effVendorSpecific = 50 ; no definition, vendor specific handling
#effCanDo = 51 ; [ptr]: "can do" string [Return value]: 0: "don't know" -1: "no" 1: "yes"
#effGetTailSize = 52 ; [Return value]: tail size (For example the reverb time of a reverb plug-in); 0 is default (return 1 for 'no tail')
#effIdle = 53 ; deprecated in VST 2.4
#effGetIcon = 54 ; deprecated in VST 2.4
#effSetViewPosition = 55 ; deprecated in VST 2.4
#effGetParameterProperties = 56 ; [index]: parameter index [ptr]: #VstParameterProperties* [Return value]: 1 If supported
#effKeysRequired = 57 ; deprecated in VST 2.4
#effGetVstVersion = 58 ; [Return value]: VST version
; VST_2_1_EXTENSIONS
; #effEditKeyDown = 59 ; [index]: ASCII character [value]: virtual key [opt]: modifiers [Return value]: 1 If key used
; #effEditKeyUp = 60 ; [index]: ASCII character [value]: virtual key [opt]: modifiers [Return value]: 1 If key used
; #effSetEditKnobMode = 61 ; [value]: knob mode 0: circular, 1: circular relativ, 2: linear (CKnobMode in VSTGUI)
; #effGetMidiProgramName = 62 ; [index]: MIDI channel [ptr]: #MidiProgramName* [Return value]: number of used programs, 0 If unsupported
; #effGetCurrentMidiProgram = 63 ; [index]: MIDI channel [ptr]: #MidiProgramName* [Return value]: index of current program
; #effGetMidiProgramCategory = 64 ; [index]: MIDI channel [ptr]: #MidiProgramCategory* [Return value]: number of used categories, 0 If unsupported
; #effHasMidiProgramsChanged = 65 ; [index]: MIDI channel [Return value]: 1 If the #MidiProgramName(s) Or #MidiKeyName(s) have changed
; #effGetMidiKeyName = 66 ; [index]: MIDI channel [ptr]: #MidiKeyName* [Return value]: true If supported, false otherwise
; #effBeginSetProgram = 67 ; no arguments @see AudioEffectX::beginSetProgram
; #effEndSetProgram = 68 ; no arguments
; VST_2_3_EXTENSIONS
; #effGetSpeakerArrangement = 69 ; [value]: input #VstSpeakerArrangement* [ptr]: output #VstSpeakerArrangement*
; #effShellGetNextPlugin = 70 ; [ptr]: buffer For plug-in name, limited To #kVstMaxProductStrLen [Return value]: Next plugin's uniqueID
; #effStartProcess = 71 ; no arguments
; #effStopProcess = 72 ; no arguments
; #effSetTotalSampleToProcess = 73; [value]: number of samples To process, offline only!
; #effSetPanLaw = 74 ; [value]: pan law [opt]: gain
; #effBeginLoadBank = 75 ; [ptr]: #VstPatchChunkInfo* [Return value]: -1: bank can't be loaded, 1: bank can be loaded, 0: unsupported
; #effBeginLoadProgram = 76 ; [ptr]: #VstPatchChunkInfo* [Return value]: -1: prog can't be loaded, 1: prog can be loaded, 0: unsupported
; VST_2_4_EXTENSIONS
#effSetProcessPrecision = 59 ; [value]: @see VstProcessPrecision
#effGetNumMidiInputChannels = 60 ; [Return value]: number of used MIDI input channels (1-15)
#effGetNumMidiOutputChannels = 61 ; [Return value]: number of used MIDI output channels (1-15)
; Symbolic precision constants used For effSetProcessPrecision.
; VstProcessPrecision
#kVstProcessPrecision32 = 0 ; single precision float (32bits)
#kVstProcessPrecision64 = 1 ; double precision (64bits)
; Parameter Properties used in #effGetParameterProperties.
Structure VstParameterProperties Align #PB_Structure_AlignC
stepFloat.f ; float step
smallStepFloat.f ; small float step
largeStepFloat.f ; large float step
label.s{#kVstMaxLabelLen} ; parameter label
flags.l ; @see VstParameterFlags
minInteger.l ; integer minimum
maxInteger.l ; integer maximum
stepInteger.l ; integer step
largeStepInteger.l ; large integer Step
shortLabel.s{#kVstMaxShortLabelLen} ; short label, recommended: 6 + delimiter
; The following are For remote controller display purposes.
; Note that the kVstParameterSupportsDisplayIndex flag must be set.
; Host can scan all parameters, And find out in what order To display them:
displayIndex.w ; index where this parameter should be displayed (starting with 0)
; Host can also possibly display the parameter group (category), such As...
; Osc 1
; Wave Detune Octave Mod
; ...If the plug-in supports it (flag #kVstParameterSupportsDisplayCategory)
category.w ; 0: no category, else group index + 1
numParametersInCategory.w ; number of parameters in category
reserved.w ; zero
categoryLabel.s{#kVstMaxCategLabelLen} ; category label, e.g. "Osc 1"
future.c[16] ; reserved for future use
EndStructure
; Flags used in #VstParameterProperties.
; VstParameterFlags
#kVstParameterIsSwitch = 1 ; parameter is a switch (on/off)
#kVstParameterUsesIntegerMinMax = 2 ; minInteger, maxInteger valid
#kVstParameterUsesFloatStep = 4 ; stepFloat, smallStepFloat, largeStepFloat valid
#kVstParameterUsesIntStep = 8 ; stepInteger, largeStepInteger valid
#kVstParameterSupportsDisplayIndex = 16 ; displayIndex valid
#kVstParameterSupportsDisplayCategory = 32 ; category, etc. valid
#kVstParameterCanRamp = 64 ; set If parameter value can ramp up/down
; Pin Properties used in #effGetInputProperties And #effGetOutputProperties.
Structure VstPinProperties Align #PB_Structure_AlignC
label.c[#kVstMaxLabelLen] ; pin name
flags.l ; @see VstPinPropertiesFlags
arrangementType.l ; @see VstSpeakerArrangementType
shortLabel.c[#kVstMaxShortLabelLen] ; short name (recommended: 6 + delimiter)
future.b[48] ; reserved for future use
EndStructure
; Flags used in #VstPinProperties.
; VstPinPropertiesFlags
#kVstPinIsActive = 1 ; pin is active, ignored by Host
#kVstPinIsStereo = 2 ; pin is first of a stereo pair
#kVstPinUseSpeaker = 4 ; #VstPinProperties::arrangementType is valid And can be used To get the wanted arrangement
; Plug-in Categories.
; VstPlugCategory
#kPlugCategUnknown = 0 ; Unknown, category Not implemented
#kPlugCategEffect = 1 ; Simple Effect
#kPlugCategSynth = 2 ; VST Instrument (Synths, samplers,...)
#kPlugCategAnalysis = 3 ; Scope, Tuner, ...
#kPlugCategMastering = 4 ; Dynamics, ...
#kPlugCategSpacializer = 5 ; Panners, ...
#kPlugCategRoomFx = 6 ; Delays And Reverbs
#kPlugSurroundFx = 7 ; Dedicated surround processor
#kPlugCategRestoration = 8 ; Denoiser, ...
#kPlugCategOfflineProcess = 9 ; Offline Process
#kPlugCategShell = 10 ; Plug-in is container of other plug-ins @see effShellGetNextPlugin
#kPlugCategGenerator = 11 ; ToneGenerator, ...
#kPlugCategMaxCount = 12 ; Marker To count the categories
; MIDI Programs
; MIDI Program Description.
Structure MidiProgramName Align #PB_Structure_AlignC
thisProgramIndex.l ; 0 or greater: fill struct for this program index
name.c[#kVstMaxNameLen] ; program name
midiProgram.c ; -1:off, 0-127
midiBankMsb.c ; -1:off, 0-127
midiBankLsb.c ; -1:off, 0-127
reserved.b ; zero
parentCategoryIndex.l ; -1:no parent category
flags.l ; omni etc. @see VstMidiProgramNameFlags
EndStructure
; Flags used in MidiProgramName.
; VstMidiProgramNameFlags
#kMidiIsOmni = 1 ; Default is multi. For omni mode, channel 0 is used For inquiries And program changes
Structure MidiProgramCategory Align #PB_Structure_AlignC
thisCategoryIndex.l ; 0 or greater: fill struct for this category index.
name.c[#kVstMaxNameLen] ; name
parentCategoryIndex.l ; -1:no parent category
flags.l ; reserved, none defined yet, zero.
EndStructure
; MIDI Key Description.
Structure MidiKeyName Align #PB_Structure_AlignC
thisProgramIndex.l ; 0 or greater: fill struct for this program index.
thisKeyNumber.l ; 0 - 127. fill struct for this key number.
keyName.c[#kVstMaxNameLen] ; key name, empty means regular key names
reserved.l ; zero
flags.l ; reserved, none defined yet, zero.
EndStructure
; Surround Setup
; Speaker Properties.
; The origin For azimuth is Right (As by math conventions dealing With radians).
; The elevation origin is also right, visualizing a rotation of a circle across the
; -pi/pi axis of the horizontal circle. Thus, an elevation of -pi/2 corresponds
; To bottom, And a speaker standing on the left, And 'beaming' upwards would have
; an azimuth of -pi, And an elevation of pi/2.
; For user Interface representation, grads are more likely To be used, And the
; origins will obviously 'shift' accordingly. */
Structure VstSpeakerProperties Align #PB_Structure_AlignC
azimuth.f ; unit: rad, range: -PI...PI, exception: 10.f for LFE channel
elevation.f ; unit: rad, range: -PI/2...PI/2, exception: 10.f For LFE channel
radius.f ; unit: meter, exception: 0.f for LFE channel
reserved.f ; zero (reserved for future use)
name.c[#kVstMaxNameLen] ; for new setups, new names should be given (L/R/C... won't do)
type.l ; VstSpeakerType
future.b[28] ; reserved for future use
EndStructure
; Speaker Arrangement.
Structure VstSpeakerArrangement Align #PB_Structure_AlignC
type.l ; e.g. #kSpeakerArr51 for 5.1 @see VstSpeakerArrangementType
numChannels.l ; number of channels in this speaker arrangement
speakers.VstSpeakerProperties[8] ; variable sized speaker array
EndStructure
; Speaker Types.
; VstSpeakerType
#kSpeakerUndefined = $7fffffff ; Undefined
#kSpeakerM = 0 ; Mono (M)
#kSpeakerL = 1 ; Left (L)
#kSpeakerR = 2 ; Right (R)
#kSpeakerC = 3 ; Center (C)
#kSpeakerLfe = 4 ; Subbass (Lfe)
#kSpeakerLs = 5 ; Left Surround (Ls)
#kSpeakerRs = 6 ; Right Surround (Rs)
#kSpeakerLc = 7 ; Left of Center (Lc)
#kSpeakerRc = 8 ; Right of Center (Rc)
#kSpeakerS = 9 ; Surround (S)
#kSpeakerCs = #kSpeakerS ; Center of Surround (Cs) = Surround (S)
#kSpeakerSl = 10 ; Side Left (Sl)
#kSpeakerSr = 11 ; Side Right (Sr)
#kSpeakerTm = 12 ; Top Middle (Tm)
#kSpeakerTfl = 13 ; Top Front Left (Tfl)
#kSpeakerTfc = 14 ; Top Front Center (Tfc)
#kSpeakerTfr = 15 ; Top Front Right (Tfr)
#kSpeakerTrl = 16 ; Top Rear Left (Trl)
#kSpeakerTrc = 17 ; Top Rear Center (Trc)
#kSpeakerTrr = 18 ; Top Rear Right (Trr)
#kSpeakerLfe2 = 19 ; Subbass 2 (Lfe2)
; User-defined speaker types, To be extended in the negative range.
; Will be handled As their corresponding speaker types With abs values:
; e.g Abs(#kSpeakerU1) == #kSpeakerL, Abs(#kSpeakerU2) == #kSpeakerR) */
; VstUserSpeakerType
Enumeration
#kSpeakerU32 = -32
#kSpeakerU31
#kSpeakerU30
#kSpeakerU29
#kSpeakerU28
#kSpeakerU27
#kSpeakerU26
#kSpeakerU25
#kSpeakerU24
#kSpeakerU23
#kSpeakerU22
#kSpeakerU21
#kSpeakerU20 ; = #kSpeakerLfe2
#kSpeakerU19 ; == #kSpeakerTrr
#kSpeakerU18 ; == #kSpeakerTrc
#kSpeakerU17 ; == #kSpeakerTrl
#kSpeakerU16 ; == #kSpeakerTfr
#kSpeakerU15 ; == #kSpeakerTfc
#kSpeakerU14 ; == #kSpeakerTfl
#kSpeakerU13 ; == #kSpeakerTm
#kSpeakerU12 ; == #kSpeakerSr
#kSpeakerU11 ; == #kSpeakerSl
#kSpeakerU10 ; == #kSpeakerCs
#kSpeakerU9 ; == #kSpeakerS
#kSpeakerU8 ; == #kSpeakerRc
#kSpeakerU7 ; == #kSpeakerLc
#kSpeakerU6 ; == #kSpeakerRs
#kSpeakerU5 ; == #kSpeakerLs
#kSpeakerU4 ; == #kSpeakerLfe
#kSpeakerU3 ; == #kSpeakerC
#kSpeakerU2 ; == #kSpeakerR
#kSpeakerU1 ; == #kSpeakerL
EndEnumeration
; Speaker Arrangement Types
; VstSpeakerArrangementType
Enumeration
#kSpeakerArrUserDefined = -2 ; user defined
#kSpeakerArrEmpty = -1 ; empty arrangement
#kSpeakerArrMono = 0 ; M
#kSpeakerArrStereo ; L R
#kSpeakerArrStereoSurround ; Ls Rs
#kSpeakerArrStereoCenter ; Lc Rc
#kSpeakerArrStereoSide ; Sl Sr
#kSpeakerArrStereoCLfe ; C Lfe
#kSpeakerArr30Cine ; L R C
#kSpeakerArr30Music ; L R S
#kSpeakerArr31Cine ; L R C Lfe
#kSpeakerArr31Music ; L R Lfe S
#kSpeakerArr40Cine ; L R C S (LCRS)
#kSpeakerArr40Music ; L R Ls Rs (Quadro)
#kSpeakerArr41Cine ; L R C Lfe S (LCRS+Lfe)
#kSpeakerArr41Music ; L R Lfe Ls Rs (Quadro+Lfe)
#kSpeakerArr50 ; L R C Ls Rs
#kSpeakerArr51 ; L R C Lfe Ls Rs
#kSpeakerArr60Cine ; L R C Ls Rs Cs
#kSpeakerArr60Music ; L R Ls Rs Sl Sr
#kSpeakerArr61Cine ; L R C Lfe Ls Rs Cs
#kSpeakerArr61Music ; L R Lfe Ls Rs Sl Sr
#kSpeakerArr70Cine ; L R C Ls Rs Lc Rc
#kSpeakerArr70Music ; L R C Ls Rs Sl Sr
#kSpeakerArr71Cine ; L R C Lfe Ls Rs Lc Rc
#kSpeakerArr71Music ; L R C Lfe Ls Rs Sl Sr
#kSpeakerArr80Cine ; L R C Ls Rs Lc Rc Cs
#kSpeakerArr80Music ; L R C Ls Rs Cs Sl Sr
#kSpeakerArr81Cine ; L R C Lfe Ls Rs Lc Rc Cs
#kSpeakerArr81Music ; L R C Lfe Ls Rs Cs Sl Sr
#kSpeakerArr102 ; L R C Lfe Ls Rs Tfl Tfc Tfr Trl Trr Lfe2
#kNumSpeakerArr
EndEnumeration
; Offline Processing
; Offline Task Description.
Structure VstOfflineTask Align #PB_Structure_AlignC
processName.c[96] ; set by plug-in
; audio access
readPosition.d ; set by plug-in/Host
writePosition.d ; set by plug-in/Host
readCount.l ; set by plug-in/Host
writeCount.l ; set by plug-in
sizeInputBuffer.l ; set by Host
sizeOutputBuffer.l ; set by Host
*inputBuffer ; set by Host
*outputBuffer ; set by Host
positionToProcessFrom.d ; set by Host
numFramesToProcess.d ; set by Host
maxFramesToWrite.d ; set by plug-in
; other Data access
*extraBuffer ; set by plug-in
value.l ; set by Host or plug-in
index.l ; set by Host or plug-in
; file attributes
numFramesInSourceFile.d ; set by Host
sourceSampleRate.d ; set by Host or plug-in
destinationSampleRate.d ; set by Host or plug-in
numSourceChannels.l ; set by Host or plug-in
numDestinationChannels.l ; set by Host or plug-in
sourceFormat.l ; set by Host
destinationFormat.l ; set by plug-in
outputText.c[512] ; set by plug-in or Host
; progress notification
progress.d ; set by plug-in
progressMode.l ; Reserved for future use
progressText.c[100] ; set by plug-in
flags.l ; set by Host and plug-in; see enum #VstOfflineTaskFlags
returnValue.l ; Reserved for future use
*hostOwned ; set by Host
*plugOwned ; set by plug-in
future.b[1024] ; Reserved for future use
EndStructure
; Flags used in #VstOfflineTask.
; VstOfflineTaskFlags
#kVstOfflineUnvalidParameter = 1 ; set by Host
#kVstOfflineNewFile = 2 ; set by Host
#kVstOfflinePlugError = 1024 ; set by plug-in
#kVstOfflineInterleavedAudio = 2048 ; set by plug-in
#kVstOfflineTempOutputFile = 4096 ; set by plug-in
#kVstOfflineFloatOutputFile = 8192 ; set by plug-in
#kVstOfflineRandomWrite = 16384 ; set by plug-in
#kVstOfflineStretch = 32768 ; set by plug-in
#kVstOfflineNoThread = 65536 ; set by plug-in
; Option passed To #offlineRead/#offlineWrite.
; VstOfflineOption
#kVstOfflineAudio = 0 ; reading/writing audio samples
#kVstOfflinePeaks = 1 ; reading graphic representation
#kVstOfflineParameter = 2 ; reading/writing parameters
#kVstOfflineMarker = 3 ; reading/writing marker
#kVstOfflineCursor = 4 ; reading/moving edit cursor
#kVstOfflineSelection = 5 ; reading/changing selection
#kVstOfflineQueryFiles = 6 ; To request the Host To call asynchronously #offlineNotify
; Structure passed To #offlineNotify And #offlineStart
Structure VstAudioFile Align #PB_Structure_AlignC
flags.l ; see enum #VstAudioFileFlags
*hostOwned ; any data private to Host
*plugOwned ; any data private to plug-in
name.c[#kVstMaxFileNameLen] ; file title
uniqueId.l ; uniquely identify a file during a session
sampleRate.d ; file sample rate
numChannels.l ; number of channels (1 for mono, 2 for stereo...)
numFrames.d ; number of frames in the audio file
format.l ; Reserved for future use
editCursorPosition.d ; -1 if no such cursor
selectionStart.d ; frame index of first selected frame, or -1
selectionSize.d ; number of frames in selection, or 0
selectedChannelsMask.l ; 1 bit per channel
numMarkers.l ; number of markers in the file
timeRulerUnit.l ; see doc for possible values
timeRulerOffset.d ; offset in time ruler (positive or negative)
tempo.d ; as BPM (Beats Per Minute)
timeSigNumerator.l ; time signature numerator
timeSigDenominator.l ; time signature denominator
ticksPerBlackNote.l ; resolution
smpteFrameRate.l ; SMPTE rate (set as in #VstTimeInfo)
future.b[64] ; Reserved for future use
EndStructure
; Flags used in #VstAudioFile.
; VstAudioFileFlags
#kVstOfflineReadOnly = 1 ; set by Host (in call #offlineNotify)
#kVstOfflineNoRateConversion = 2 ; set by Host (in call #offlineNotify)
#kVstOfflineNoChannelChange = 4 ; set by Host (in call #offlineNotify)
#kVstOfflineCanProcessSelection = 1024 ; set by plug-in (in call #offlineStart)
#kVstOfflineNoCrossfade = 2048 ; set by plug-in (in call #offlineStart)
#kVstOfflineWantRead = 4096 ; set by plug-in (in call #offlineStart)
#kVstOfflineWantWrite = 8192 ; set by plug-in (in call #offlineStart)
#kVstOfflineWantWriteMarker = 16384 ; set by plug-in (in call #offlineStart)
#kVstOfflineWantMoveCursor = 32768 ; set by plug-in (in call #offlineStart)
#kVstOfflineWantSelect = 65536 ; set by plug-in (in call #offlineStart)
; Audio file marker.
Structure VstAudioFileMarker Align #PB_Structure_AlignC
position.d ; marker position
name.c[32] ; marker name
type.l ; marker type
id.l ; marker identifier
reserved.l ; reserved for future use
EndStructure
; Others
; structure used For #openWindow And #closeWindow (deprecated in VST 2.4).
Structure VstWindow Align #PB_Structure_AlignC
title.c[128]
xPos.w
yPos.w
width.w
height.w
style.w
*parent
*userHandle
*winHandle
future.b[104]
EndStructure
; Structure used For keyUp/keyDown.
Structure VstKeyCode Align #PB_Structure_AlignC
character.l ; ASCII character
virt.b ; @see VstVirtualKey
modifier.b ; @see VstModifierKey
EndStructure
; Platform-independent definition of Virtual Keys (used in #VstKeyCode).
Enumeration ; VstVirtualKey
#VKEY_BACK = 1
#VKEY_TAB
#VKEY_CLEAR
#VKEY_RETURN
#VKEY_PAUSE
#VKEY_ESCAPE
#VKEY_SPACE
#VKEY_NEXT
#VKEY_END
#VKEY_HOME
#VKEY_LEFT
#VKEY_UP
#VKEY_RIGHT
#VKEY_DOWN
#VKEY_PAGEUP
#VKEY_PAGEDOWN
#VKEY_SELECT
#VKEY_PRINT
#VKEY_ENTER
#VKEY_SNAPSHOT
#VKEY_INSERT
#VKEY_DELETE
#VKEY_HELP
#VKEY_NUMPAD0
#VKEY_NUMPAD1
#VKEY_NUMPAD2
#VKEY_NUMPAD3
#VKEY_NUMPAD4
#VKEY_NUMPAD5
#VKEY_NUMPAD6
#VKEY_NUMPAD7
#VKEY_NUMPAD8
#VKEY_NUMPAD9
#VKEY_MULTIPLY
#VKEY_ADD
#VKEY_SEPARATOR
#VKEY_SUBTRACT
#VKEY_DECIMAL
#VKEY_DIVIDE
#VKEY_F1
#VKEY_F2
#VKEY_F3
#VKEY_F4
#VKEY_F5
#VKEY_F6
#VKEY_F7
#VKEY_F8
#VKEY_F9
#VKEY_F10
#VKEY_F11
#VKEY_F12
#VKEY_NUMLOCK
#VKEY_SCROLL
#VKEY_SHIFT
#VKEY_CONTROL
#VKEY_ALT
#VKEY_EQUALS
EndEnumeration
; Modifier flags used in #VstKeyCode.
; VstModifierKey
#MODIFIER_SHIFT = 1 ; Shift
#MODIFIER_ALTERNATE = 2 ; Alt
#MODIFIER_COMMAND = 4 ; Control on Mac
#MODIFIER_CONTROL = 8 ; Ctrl on PC, Apple on Mac
; File filter used in #VstFileSelect.
Structure VstFileType Align #PB_Structure_AlignC
name.c[128] ; display name
macType.c[8] ; MacOS type
dosType.c[8] ; Windows file extension
unixType.c[8] ; Unix file extension
mimeType1.c[128] ; MIME type
mimeType2.c[128] ; additional MIME type
EndStructure
; File Selector Description used in #audioMasterOpenFileSelector.
Structure VstFileSelect Align #PB_Structure_AlignC
command.l ; @see VstFileSelectCommand
type.l ; @see VstFileSelectType
macCreator.l ; optional: 0 = no creator
nbFileTypes.l ; number of fileTypes
*fileTypes.VstFileType ; list of fileTypes @see VstFileType
title.c[1024] ; text to display in file selector's title
*initialPath.string ; initial path
*returnPath.String ; use with #kVstFileLoad and #kVstDirectorySelect. null: Host allocates memory, plug-in must call #closeOpenFileSelector!
sizeReturnPath.l ; size of allocated memory for return paths
*returnMultiplePaths.String ; use with kVstMultipleFilesLoad. Host allocates memory, plug-in must call #closeOpenFileSelector!
nbReturnPath.l ; number of selected paths
reserved.i ; reserved for Host application
future.b[116] ; reserved for future use
EndStructure
; Command constants used in #VstFileSelect Structure.
Enumeration VstFileSelectCommand
#kVstFileLoad = 0 ; For loading a file
#kVstFileSave ; For saving a file
#kVstMultipleFilesLoad ; For loading multiple files
#kVstDirectorySelect ; For selecting a directory/folder
EndEnumeration
; Types used in #VstFileSelect Structure.
#kVstFileType = 0 ; regular file selector
; Structure used For #effBeginLoadBank/#effBeginLoadProgram.
Structure VstPatchChunkInfo Align #PB_Structure_AlignC
version.l ; Format Version (should be 1)
pluginUniqueID.l ; UniqueID of the plug-in
pluginVersion.l ; Plug-in Version
numElements.l ; Number of Programs (Bank) or Parameters (Program)
future.c[48] ; Reserved for future use
EndStructure
; PanLaw Type.
; VstPanLawType
#kLinearPanLaw = 0 ; L = pan * M; R = (1 - pan) * M;
#kEqualPowerPanLaw = 1 ; L = Pow (pan, 0.5) * M; R = pow ((1 - pan), 0.5) * M;
; Process Levels returned by #audioMasterGetCurrentProcessLevel.
Enumeration ; VstProcessLevels
#kVstProcessLevelUnknown = 0 ; Not supported by Host
#kVstProcessLevelUser ; 1: currently in user thread (GUI)
#kVstProcessLevelRealtime ; 2: currently in audio thread (where process is called)
#kVstProcessLevelPrefetch ; 3: currently in 'sequencer' thread (MIDI, timer etc)
#kVstProcessLevelOffline ; 4: currently offline processing And thus in user thread
EndEnumeration
; Automation States returned by #audioMasterGetAutomationState.
Enumeration ; VstAutomationStates
#kVstAutomationUnsupported = 0 ; Not supported by Host
#kVstAutomationOff ; off
#kVstAutomationRead ; Read
#kVstAutomationWrite ; write
#kVstAutomationReadWrite ; Read And write
EndEnumeration
; Plug-in CanDo strings
Global canDoSendVstEvents.s = "sendVstEvents" ; plug-in will send Vst events to Host
Global canDoSendVstMidiEvent.s = "sendVstMidiEvent" ; plug-in will send MIDI events to Host
Global canDoReceiveVstEvents.s = "receiveVstEvents" ; plug-in can receive MIDI events from Host
Global canDoReceiveVstMidiEvent.s = "receiveVstMidiEvent" ; plug-in can receive MIDI events from Host
Global canDoReceiveVstTimeInfo.s = "receiveVstTimeInfo" ; plug-in can receive Time info from Host
Global canDoOffline.s = "offline" ; plug-in supports offline functions (#offlineNotify, #offlinePrepare, #offlineRun)
Global canDoMidiProgramNames.s = "midiProgramNames" ; plug-in supports function #getMidiProgramName ()
Global canDoBypass.s = "bypass" ; plug-in supports function #setBypass ()
Code: Select all
; file VSTGUI.pbi
Global winrect.ERect
winrect\top = 10
winrect\left = 10
winrect\bottom = 500
winrect\right = 500
Global hWndMain
Global hbutton
Global htext
Global hcontainer
Global htrackbar
Global hinstance = GetModuleHandle_(#Null)
Global miditext0.s
Global miditext1.s
Global miditext2.s
Global miditype.s
Procedure gadgetshandler()
MessageRequester("event", "click " + Str(EventGadget()))
EndProcedure
Procedure GUIOpen(*parenthandle)
hWndMain = OpenWindow(#PB_Any, 0, 0, winrect\bottom, winrect\right, "", #PB_Window_NoActivate)
SetParent_(WindowID(hWndMain), *parenthandle)
StartDrawing(WindowOutput(hWndMain))
DrawText(20, 20, "ev1 " + miditext0)
DrawText(20, 50, "ev2 " + miditext1)
DrawText(20, 100, "ev3 " + miditext2)
TextGadget(htext, 20, 300, 100, 100, miditype)
; DrawText(20, 350, "cando " + candostring1)
StopDrawing()
hcontainer = ContainerGadget(#PB_Any, 10, 10, 400, 400)
hbutton = ButtonGadget(#PB_Any, 20, 150, 150, 150, "my button")
htrackbar = TrackBarGadget(#PB_Any, 300, 100, 150, 150, 0, 100, #PB_TrackBar_Vertical)
GadgetToolTip(hbutton, "tooltip for button")
CloseGadgetList()
BindGadgetEvent(hbutton, @gadgetshandler())
ProcedureReturn #True
EndProcedure
Procedure GUIClose()
CloseWindow(hWndMain)
EndProcedure
Procedure GetRect(*rect)
*rect = @winrect
ProcedureReturn #True
EndProcedure
Code: Select all
; general file VST_plugin.pb
; 18.10.2020 basic example
EnableExplicit
XIncludeFile "aeffectx.pbi"
XIncludeFile "vstgui.pbi"
Global channels.l = 2
Global numparams.l = 3
Global.f leftparam = 1.0, rightparam = 1.0, ModeValue
Global SampleRate.f
Global BlockSize.l
Global NumPrograms.l = 5
Global CurProgram.l = 0
Global NameProgram.s
Define.l currentNote, currentVelocity, currentDelta, noteIsOn
Enumeration ParameterIndex
#LeftVolume
#RightVolume
#ModeVolume
#kVSTparameterLen = 12
EndEnumeration
Procedure.f LeftSample(inputsample.f)
ProcedureReturn inputsample * leftparam
EndProcedure
Procedure.f RightSample(inputsample.f)
ProcedureReturn inputsample * rightparam
EndProcedure
; other procedures
Procedure suspend()
EndProcedure
Procedure resume()
EndProcedure
Procedure.l getProgram()
ProcedureReturn curprogram
EndProcedure
Procedure setProgram(program.l)
CurProgram = program
EndProcedure
Procedure.l getProgramNameIndexed (category.l, index.l, *text)
If index < NumPrograms
PokeS(*text, NameProgram, #kVstMaxProgNameLen, #PB_Ascii)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure getProgramName(*name)
PokeS(*name, "Basic preset", #kVstMaxProgNameLen, #PB_Ascii)
EndProcedure
Procedure setProgramName(*name)
NameProgram = PeekS(*name, #kVstMaxProgNameLen, #PB_Ascii)
EndProcedure
Procedure getParameterName(index.l, *text)
Select index
Case #LeftVolume
PokeS(*text, "Left volume", #kVSTparameterLen, #PB_Ascii)
Case #RightVolume
PokeS(*text, "Right volume", #kVSTparameterLen, #PB_Ascii)
Case #ModeVolume
PokeS(*text, "Mode", #kVSTparameterLen, #PB_Ascii)
EndSelect
EndProcedure
Procedure getParameterLabel(index.l, *text)
Select index
Case #LeftVolume
PokeS(*text, StrF(leftparam, 4), SizeOf(Float), #PB_Ascii)
Case #RightVolume
PokeS(*text, StrF(rightparam, 4), SizeOf(Float), #PB_Ascii)
Case #ModeVolume
Select Int(ModeValue * 1000.0)
Case 0
PokeS(*text, "left", #kVstMaxShortLabelLen, #PB_Ascii)
Case 1
PokeS(*text, "center", #kVstMaxShortLabelLen, #PB_Ascii)
Case 2
PokeS(*text, "right", #kVstMaxShortLabelLen, #PB_Ascii)
Default
PokeS(*text, "empty", #kVstMaxShortLabelLen, #PB_Ascii)
EndSelect
EndSelect
EndProcedure
Procedure.l canDo(*text)
If CompareMemoryString(*text, @canDoReceiveVstEvents, #PB_String_NoCase, -1, #PB_Ascii) = 0
ProcedureReturn 1
EndIf
If CompareMemoryString(*text, @canDoReceiveVstMidiEvent, #PB_String_NoCase, -1, #PB_Ascii) = 0
ProcedureReturn 1
EndIf
ProcedureReturn -1
EndProcedure
Procedure.l getNumMidiOutputChannels()
ProcedureReturn 1
EndProcedure
Procedure.l getNumMidiInputChannels()
ProcedureReturn 1
EndProcedure
ProcedureC.l ProcessEvents(*EVs.VstEvents)
Protected ve.VstEvent, me.VstMidiEvent
Protected i.l
For i = 0 To *EVs\numEvents
If *EVs\events[i]\type = #kVstMidiType
CopyStructure(@ve, @me.VstMidiEvent, VstMidiEvent)
miditype = Chr(me\type)
miditext0 = Chr(me\mididata[0])
miditext1 = Chr(me\mididata[1])
miditext2 = Chr(me\mididata[2])
EndIf
Next i
ProcedureReturn #True
EndProcedure
; procedures for VST sdk
ProcedureC.i DispatcherProc(*d.AEffect, opcode.l, index.l, Value.i, *ptr, opt.f)
Protected result.i
If opcode = #effClose
FreeStructure(*d)
ElseIf opcode = #effSetSampleRate
SampleRate = opt
ElseIf opcode = #effSetBlockSize
BlockSize = value
ElseIf opcode = #effCanDo
result = CanDo(*ptr)
ElseIf opcode = #effgetNumMidiOutputChannels
result = getNumMidiOutputChannels()
ElseIf opcode = #effgetNumMidiInputChannels
result = getNumMidiInputChannels()
ElseIf opcode = #effProcessEvents
result = ProcessEvents(*ptr)
ElseIf opcode = #effSetProgram
setProgram(Value)
ElseIf opcode = #effGetProgram
result = getProgram()
ElseIf opcode = #effSetProgramName
setProgramName(*ptr)
ElseIf opcode = #effGetProgramName
getProgramName(*ptr)
ElseIf opcode = #effGetProgramNameIndexed
result = getProgramNameIndexed(value, index, *ptr)
ElseIf opcode = #effGetParamLabel
getParameterLabel(index, *ptr)
ElseIf opcode = #effGetParamName
getParameterName(index, *ptr)
ElseIf opcode = #effMainsChanged
If Not Value
suspend()
Else
resume()
EndIf
ElseIf opcode = #effGetPlugCategory
result = #kPlugCategEffect | #kPlugCategAnalysis
ElseIf opcode = #effGetEffectName
PokeS(*ptr, "test plugin", #kVstMaxEffectNameLen, #PB_Ascii)
ElseIf opcode = #effGetVendorString
PokeS(*ptr, "Alex Longard", #kVstMaxVendorStrLen, #PB_Ascii)
ElseIf opcode = #effEditGetRect
result = GetRect(*ptr)
ElseIf opcode = #effEditOpen
GUIOpen(*ptr)
ElseIf opcode = #effEditClose
GUIClose()
EndIf
ProcedureReturn result
EndProcedure
ProcedureC ProcessReplacingProc(*ap.AEffect, *inputs, *outputs, sampleframes.l)
Protected *In1, *In2, *Out1, *Out2, i.i
*In1 = PeekI(*inputs)
*Out1 = PeekI(*outputs)
*In2 = PeekI(*inputs + SizeOf(integer))
*Out2 = PeekI(*outputs + SizeOf(integer))
For i = 0 To sampleframes - 1
PokeF(*Out1 + i * SizeOf(float), LeftSample(PeekF(*In1 + i * SizeOf(float))))
PokeF(*Out2 + i * SizeOf(float), RightSample(PeekF(*In2 + i * SizeOf(float))))
Next i
EndProcedure
ProcedureC ProcessDoubleReplacingProc(*ap.AEffect, *inputs, *outputs, sampleframes.l)
Protected *In1, *In2, *Out1, *Out2, i.i
*In1 = PeekI(*inputs)
*Out1 = PeekI(*outputs)
*In2 = PeekI(*inputs + SizeOf(integer))
*Out2 = PeekI(*outputs + SizeOf(integer))
For i = 0 To sampleframes - 1
PokeD(*Out1 + i * SizeOf(Double), LeftSample(PeekD(*In1 + i * SizeOf(Double))))
PokeD(*Out2 + i * SizeOf(Double), RightSample(PeekD(*In2 + i * SizeOf(Double))))
Next i
EndProcedure
ProcedureC SetParameterProc(*asp.AEffect, index.l, value.f)
Select index
Case #LeftVolume
leftparam = value
Case #RightVolume
rightparam = value
Case #ModeVolume
ModeValue = value
EndSelect
EndProcedure
ProcedureC.f GetParameterProc(*agp.AEffect, index.l)
Protected result.f = 0
Select index
Case #LeftVolume
result = leftparam
Case #RightVolume
result = rightparam
Case #ModeVolume
result = ModeValue
EndSelect
ProcedureReturn result
EndProcedure
ProcedureCDLL VSTPluginMain(*audioMaster.AudioMasterCallback)
Protected *Aef.AEffect = AllocateStructure(AEffect)
*aef\magic = #kEffectMagic
*aef\dispatcher = @DispatcherProc()
*aef\setParameter = @SetParameterProc()
*aef\getParameter = @GetParameterProc()
*aef\numPrograms = NumPrograms
*aef\numParams = numparams
*aef\numInputs = channels
*aef\numOutputs = channels
*aef\flags = #effFlagsHasEditor | #effFlagsCanDoubleReplacing ;| #effFlagsIsSynth
*aef\processReplacing = @ProcessReplacingProc()
*aef\processDoubleReplacing = @ProcessDoubleReplacingProc()
*aef\uniqueID = 02081987
*aef\version = 1
*aef\Object = 0
ProcedureReturn *aef
EndProcedure