// This was created from released VST2.x plugins, and is technically under the 2-clause BSD license. // Depending on which country you are in, Steinberg can do fuck all about this. Notable countries for // this are most members of the United States of America, the entirety of Europe, Japan, and Russia. // Consult a lawyer if you don't know if clean room reverse engineering is allowed in your country. // See README.md for all information. // Known additional information: // - Function call standard seems to be stdcall. // - Everything is aligned to 8 bytes. // VST Versioning: // - Base-10, thus can't store many version numbers. // - Always four components, with the major one being able to store the most numbers. // - Format is A...ABCD, so 1.2.3.4 would turn into 1234. // Modified 2024-02-05 by Marc Burns // - Downloaded this file from https://github.com/Xaymar/vst2sdk // - Downloaded Kushview Element public edition from https://github.com/kushview/element/releases/tag/0.46.6 // - Loaded + analyzed Element in Ghidra 11.0.1 // - Added enums and structs until JUCE could compile, referencing Element's decompilation in Ghidra // against the JUCE source code to retrieve unknown names and enum values. Struct definitions were // reconstructed from access patterns in Element. #pragma once #ifndef VST2SDK_VST_H #define VST2SDK_VST_H #define VSTCALLBACK #define VST_ALIGNMENT 8 #define VST_MAGICNUMBER 'VstP' // Common VST buffer lengths: // 8: OpCodes(GetLabel, GetName, GetValue) #define VST_BUFFER_8 8 // 16: #define VST_BUFFER_16 16 // 24: OpCodes? #define VST_BUFFER_24 24 // 32: OpCodes(EffectName) #define VST_BUFFER_32 32 #define VST_EFFECT_BUFFER_SIZE 32 // 64: OpCodes(ProductName, VendorName) #define VST_BUFFER_64 64 #define VST_VENDOR_BUFFER_SIZE VST_BUFFER_64 #define VST_PRODUCT_BUFFER_SIZE VST_BUFFER_64 #define VST_NAME_BUFFER_SIZE VST_BUFFER_64 // 100: #define VST_BUFFER_100 100 #define VST_MAX_CHANNELS 32 // Couldn't find any audio editing software which would attempt to add more channels. #pragma pack(push, VST_ALIGNMENT) #ifdef __cplusplus extern "C" { #endif /******************************************************************************* |* Enumeration |*/ enum VST_VERSION { VST_VERSION_1 = 0, // Anything before 2.0, used by official plug-ins. VST_VERSION_1_0_0_0 = 1000, // 1.0, used by some third-party plug-ins. VST_VERSION_1_1_0_0 = 1100, // 1.1, used by some third-party plug-ins. VST_VERSION_2 = 2, // 2.0, used by official plug-ins. VST_VERSION_2_0_0_0 = 2000, // 2.0, used by some third-party plug-ins. VST_VERSION_2_1_0_0 = 2100, // 2.1 VST_VERSION_2_2_0_0 = 2200, // 2.2 VST_VERSION_2_3_0_0 = 2300, // 2.3 VST_VERSION_2_4_0_0 = 2400, // 2.4 // Pad to force 32-bit number. _VST_VERSION_PAD = 0xFFFFFFFFul, }; enum VstPlugCategory { kPlugCategUnknown = 0, kPlugCategEffect = 1, kPlugCategSynth = 2, kPlugCategAnalysis = 3, kPlugCategMastering = 4, kPlugCategSpacializer = 5, kPlugCategRoomFx = 6, kPlugSurroundFx = 7, // weird kPlugCategRestoration = 8, kPlugCategOfflineProcess = 9, kPlugCategShell = 10, kPlugCategGenerator = 11, kPlugCategMaxCount, // Pad to force 32-bit number. _VST_CATEGORY_PAD = 0xFFFFFFFFul, }; enum VST_EFFECT_OPCODE { /* Create/Initialize the effect (if it has not been created already). * * @return Always 0. */ VST_EFFECT_OPCODE_00 = 0x00, VST_EFFECT_OPCODE_CREATE = 0x00, VST_EFFECT_OPCODE_INITIALIZE = 0x00, effOpen = 0x00, /* Destroy the effect (if there is any) and free its memory. * * This should destroy the actual object created by VST_ENTRYPOINT. * * @return Always 0. */ VST_EFFECT_OPCODE_01 = 0x01, VST_EFFECT_OPCODE_DESTROY = 0x01, effClose = 0x01, /* Set Program * * */ VST_EFFECT_OPCODE_02 = 0x02, effSetProgram = 0x02, /* Get Program * * */ VST_EFFECT_OPCODE_03 = 0x03, effGetProgram = 0x03, /* Set Program Name * * */ VST_EFFECT_OPCODE_04 = 0x04, effSetProgramName = 0x04, /* Get Program Name * * "Returns 0. If ptr is valid, sets the first byte of ptr to 0 then returns 0." */ VST_EFFECT_OPCODE_05 = 0x05, effGetProgramName = 0x05, /* Get the value? label for the parameter. * * @param p_int1 Parameter index. * @param p_ptr 'char[8]' * @return 0 on success, 1 on failure. */ VST_EFFECT_OPCODE_06 = 0x06, VST_EFFECT_OPCODE_PARAM_GETLABEL = 0x06, effGetParamLabel = 0x06, /* Get the string value for the parameter. * * @param p_int1 Parameter index. * @param p_ptr 'char[8]' * @return 0 on success, 1 on failure. */ VST_EFFECT_OPCODE_07 = 0x07, VST_EFFECT_OPCODE_PARAM_GETVALUE = 0x07, effGetParamDisplay = 0x07, /* Get the name for the parameter. * * @param p_int1 Parameter index. * @param p_ptr 'char[8]' * @return 0 on success, 1 on failure. */ VST_EFFECT_OPCODE_08 = 0x08, VST_EFFECT_OPCODE_PARAM_GETNAME = 0x08, effGetParamName = 0x08, /* * * */ VST_EFFECT_OPCODE_09 = 0x09, /* Set the new sample rate for the plugin to use. * * @param p_float New sample rate as a float (double on 64-bit because register upgrades). */ VST_EFFECT_OPCODE_0A = 0x0A, VST_EFFECT_OPCODE_SETSAMPLERATE = 0x0A, VST_EFFECT_OPCODE_SET_SAMPLE_RATE = 0x0A, effSetSampleRate = 0x0A, /* Sets the block size, which is the maximum number of samples passed into the effect via process calls. * * @param p_int2 The maximum number of samples to be passed in. */ VST_EFFECT_OPCODE_0B = 0x0B, VST_EFFECT_OPCODE_SETBLOCKSIZE = 0x0B, VST_EFFECT_OPCODE_SET_BLOCK_SIZE = 0x0B, effSetBlockSize = 0x0B, /* Effect processing should be suspended/paused. * * Unclear if this is should result in a flush of buffers. * * @param p_int2 0 if the effect should suspend processing, 1 if it should resume. */ VST_EFFECT_OPCODE_0C = 0x0C, VST_EFFECT_OPCODE_SUSPEND = 0x0C, effMainsChanged = 0x0C, /* Retrieve the client rect size of the plugins window. * If no window has been created, returns the default rect. * * @param p_ptr Pointer of type 'struct vst_rect*'. * @return On success, returns 1 and updates p_ptr to the rect. On failure, returns 0. */ VST_EFFECT_OPCODE_0D = 0x0D, VST_EFFECT_OPCODE_WINDOW_GETRECT = 0x0D, effEditGetRect = 0x0D, /* Create the window for the plugin. * * @param p_ptr HWND of the parent window. * @return 0 on failure, or HWND on success. */ VST_EFFECT_OPCODE_0E = 0x0E, VST_EFFECT_OPCODE_WINDOW_CREATE = 0x0E, effEditOpen = 0x0E, /* Destroy the plugins window. * * @return Always 0. */ VST_EFFECT_OPCODE_0F = 0x0F, VST_EFFECT_OPCODE_WINDOW_DESTROY = 0x0F, effEditClose = 0x0F, /* * * */ VST_EFFECT_OPCODE_10 = 0x10, /* * * */ VST_EFFECT_OPCODE_11 = 0x11, /* * * */ VST_EFFECT_OPCODE_12 = 0x12, /* * * */ VST_EFFECT_OPCODE_13 = 0x13, effEditIdle = 0x13, /* * * */ VST_EFFECT_OPCODE_14 = 0x14, effEditTop = 0x14, /* * * */ VST_EFFECT_OPCODE_15 = 0x15, /* Always returns the FourCC 'NvEF' (0x4E764566). */ VST_EFFECT_OPCODE_16 = 0x16, effIdentify = 0x16, /* Get Chunk * * */ VST_EFFECT_OPCODE_17 = 0x17, effGetChunk = 0x17, /* Set Chunk * * */ VST_EFFECT_OPCODE_18 = 0x18, effSetChunk = 0x18, // VST2.x starts here. /* * * */ VST_EFFECT_OPCODE_19 = 0x19, effProcessEvents = 0x19, /* Can the parameter be automated? * * @param p_int1 Index of the parameter. * @return 1 if the parameter can be automated, otherwise 0. */ VST_EFFECT_OPCODE_1A = 0x1A, VST_EFFECT_OPCODE_PARAM_ISAUTOMATABLE = 0x1A, effCanBeAutomated = 0x1A, // confirmed w/ ghidra /* * * */ VST_EFFECT_OPCODE_1B = 0x1B, /* * * */ VST_EFFECT_OPCODE_1C = 0x1C, /* * * */ VST_EFFECT_OPCODE_1D = 0x1D, // See VST_EFFECT_OPCODE_05 effGetProgramNameIndexed = 0x1D, /* * * */ VST_EFFECT_OPCODE_1E = 0x1E, /* Input connected. * * */ VST_EFFECT_OPCODE_1F = 0x1F, effConnectInput = 0x1F, /* Input disconnected. * * */ VST_EFFECT_OPCODE_20 = 0x20, effConnectOutput = 0x20, /* Retrieve the name of the input channel at the given index. * * @param p_int1 Index of the input to get the name for. * @param p_ptr Pointer to a char* buffer able to hold at minimum 20 characters. Might need to be 32 even. * @return 0 on failure, 1 on success. */ VST_EFFECT_OPCODE_21 = 0x21, VST_EFFECT_OPCODE_INPUT_GETCHANNELNAME = 0x21, VST_EFFECT_OPCODE_INPUT_CHANNEL_NAME = 0x21, effGetInputProperties = 0x21, /* Retrieve the name of the output channel at the given index. * * @param p_int1 Index of the output to get the name for. * @param p_ptr Pointer to a char* buffer able to hold at minimum 20 characters. Might need to be 32 even. * @return 0 on failure, 1 on success. */ VST_EFFECT_OPCODE_22 = 0x22, VST_EFFECT_OPCODE_OUTPUT_GETCHANNELNAME = 0x22, VST_EFFECT_OPCODE_OUTPUT_CHANNEL_NAME = 0x22, effGetOutputProperties = 0x22, /* Retrieve category of this effect. * * @return The category that this effect is in, see VST_CATEGORY. */ VST_EFFECT_OPCODE_23 = 0x23, VST_EFFECT_OPCODE_EFFECT_CATEGORY = 0x23, effGetPlugCategory = 0x23, /* * * */ VST_EFFECT_OPCODE_24 = 0x24, /* * * */ VST_EFFECT_OPCODE_25 = 0x25, /* * * */ VST_EFFECT_OPCODE_26 = 0x26, /* * * */ VST_EFFECT_OPCODE_27 = 0x27, /* * * */ VST_EFFECT_OPCODE_28 = 0x28, /* * * */ VST_EFFECT_OPCODE_29 = 0x29, /* Set the speaker arrangement * * @param p_int2 (vst_speaker_arrangement*) Pointer to a pointer to the speaker arrangement for the input. * @param p_ptr (vst_speaker_arrangement*) Pointer to a pointer to the speaker arrangement for the output. */ VST_EFFECT_OPCODE_2A = 0x2A, VST_EFFECT_OPCODE_SET_SPEAKER_ARRANGEMENT = 0x2A, effSetSpeakerArrangement = 0x2A, /* * * */ VST_EFFECT_OPCODE_2B = 0x2B, /* Enable/Disable bypassing the effect. * * @param p_int2 Zero if bypassing the effect is disabled, otherwise 1. */ VST_EFFECT_OPCODE_2C = 0x2C, VST_EFFECT_OPCODE_BYPASS = 0x2C, effSetBypass = 0x2C, /* Retrieve the effect name into the ptr buffer. * * @param p_ptr char[64] Buffer containing a zero-terminated effect information string. May be shorter than 64 bytes on older hosts. * @return Always 0, even on failure. */ VST_EFFECT_OPCODE_2D = 0x2D, VST_EFFECT_OPCODE_GETNAME = 0x2D, VST_EFFECT_OPCODE_EFFECT_NAME = 0x2D, effGetEffectName = 0x2D, /* Translate an error code to a string. * * @param p_ptr char[256] Buffer that should contain a zero-terminated error string. */ VST_EFFECT_OPCODE_2E = 0x2E, VST_EFFECT_OPCODE_TRANSLATE_ERROR = 0x2E, /* Retrieve the vendor name into the ptr buffer. * * @param p_ptr char[64] Buffer containing a zero-terminated vendor information string. May be shorter than 64 bytes on older hosts. * @return Always 0, even on failure. */ VST_EFFECT_OPCODE_2F = 0x2F, VST_EFFECT_OPCODE_GETVENDOR = 0x2F, VST_EFFECT_OPCODE_VENDOR_NAME = 0x2F, effGetVendorString = 0x2F, /* See VST_EFFECT_OPCODE_GETNAME * * Rarely used, if at all even supported. Not sure what the purpose of this is even. */ VST_EFFECT_OPCODE_30 = 0x30, VST_EFFECT_OPCODE_GETNAME2 = 0x30, VST_EFFECT_OPCODE_PRODUCT_NAME = 0x30, effGetProductString = 0x30, /* Retrieve the vendor version in return value. * * @return Version. */ VST_EFFECT_OPCODE_31 = 0x31, VST_EFFECT_OPCODE_GETVENDORVERSION = 0x31, VST_EFFECT_OPCODE_VENDOR_VERSION = 0x31, effGetVendorVersion = 0x31, /* User defined OP Code, for custom interaction. * */ VST_EFFECT_OPCODE_32 = 0x32, VST_EFFECT_OPCODE_CUSTOM = 0x32, effVendorSpecific = 0x32, /* Test for support of a specific named feature. * * @param p_ptr Pointer to a zero-terminated buffer containing the feature name. * @return Non-zero if the feature is supported, otherwise 0. */ VST_EFFECT_OPCODE_33 = 0x33, VST_EFFECT_OPCODE_SUPPORTS = 0x33, effCanDo = 0x33, /* Number of samples that are at the tail at the end of playback. * * @return 0 or 1 for no tail, > 1 for number of samples to tail. */ VST_EFFECT_OPCODE_34 = 0x34, VST_EFFECT_OPCODE_GETTAILSAMPLES = 0x34, VST_EFFECT_OPCODE_TAIL_SAMPLES = 0x34, effGetTailSize = 0x34, /* * * */ VST_EFFECT_OPCODE_35 = 0x35, effIdle = 0x35, /* * * */ VST_EFFECT_OPCODE_36 = 0x36, /* * * */ VST_EFFECT_OPCODE_37 = 0x37, /* Parameter Properties * * @param p_ptr vst_parameter_properties* * @return 1 if supported, otherwise 0. */ VST_EFFECT_OPCODE_38 = 0x38, VST_EFFECT_OPCODE_GET_PARAMETER_PROPERTIES = VST_EFFECT_OPCODE_38, effGetParameterProperties = 0x38, VST_EFFECT_OPCODE_39 = 0x39, VST_EFFECT_OPCODE_GET_KEYS_REQUIRED = VST_EFFECT_OPCODE_39, effKeysRequired = 0x39, /* Retrieve the VST Version supported. * * @return Return 0 for <2.0, 2 for 2.0, 2100 for 2.1, 2200 for 2.2, 2300 for 2.3, etc. */ VST_EFFECT_OPCODE_3A = 0x3A, VST_EFFECT_OPCODE_VST_VERSION = 0x3A, // VST 2.1 or later /* * * */ VST_EFFECT_OPCODE_3B = 0x3B, /* * * */ VST_EFFECT_OPCODE_3C = 0x3C, /* * * */ VST_EFFECT_OPCODE_3D = 0x3D, /* * * */ VST_EFFECT_OPCODE_3E = 0x3E, /* * * */ VST_EFFECT_OPCODE_3F = 0x3F, /* * * */ VST_EFFECT_OPCODE_40 = 0x40, /* * * */ VST_EFFECT_OPCODE_41 = 0x41, /* * * */ VST_EFFECT_OPCODE_42 = 0x42, /* * * */ VST_EFFECT_OPCODE_43 = 0x43, /* * * */ VST_EFFECT_OPCODE_44 = 0x44, // VST 2.3 or later /* Retrieve the speaker arrangement. * * @param p_int2 (vst_speaker_arrangement**) Pointer to a pointer to the speaker arrangement for the input. * @param p_ptr (vst_speaker_arrangement**) Pointer to a pointer to the speaker arrangement for the output. */ VST_EFFECT_OPCODE_45 = 0x45, VST_EFFECT_OPCODE_GET_SPEAKER_ARRANGEMENT = 0x45, effGetSpeakerArrangement = 0x45, /* * * */ VST_EFFECT_OPCODE_46 = 0x46, effShellGetNextPlugin = 0x46, /* Begin processing of audio. * * * */ VST_EFFECT_OPCODE_PROCESS_BEGIN = 0x47, effStartProcess = 0x47, /* End processing of audio. * * * */ VST_EFFECT_OPCODE_PROCESS_END = 0x48, effStopProcess = 0x48, /* * * */ VST_EFFECT_OPCODE_49 = 0x49, /* * * */ VST_EFFECT_OPCODE_4A = 0x4A, /* * * */ VST_EFFECT_OPCODE_4B = 0x4B, /* * * */ VST_EFFECT_OPCODE_4C = 0x4C, // VST 2.4 or later /* * * */ VST_EFFECT_OPCODE_4D = 0x4D, effSetProcessPrecision = 0x4D, /* * * */ VST_EFFECT_OPCODE_4E = 0x4E, /* * * */ VST_EFFECT_OPCODE_4F = 0x4F, // Highest number of known OPCODE. VST_EFFECT_OPCODE_MAX, // Pad to force 32-bit number. _VST_EFFECT_OPCODE_PAD = 0xFFFFFFFFul, }; // ghidra enum VST_HOST_OPCODE { /* * @param int1 -1 or Parameter Index * @return Expected to return... something. */ VST_HOST_OPCODE_00 = 0x00, // cb(vst, 0x00, ?, 0, 0); audioMasterAutomate = 0x00, VST_HOST_OPCODE_01 = 0x01, audioMasterVersion = 0x01, VST_HOST_OPCODE_02 = 0x02, // bool cb(0, 0x02, 0, 0, 0); audioMasterCurrentId = 0x02, VST_HOST_OPCODE_03 = 0x03, audioMasterIdle = 0x03, VST_HOST_OPCODE_04 = 0x04, audioMasterPinConnected = 0x04, VST_HOST_OPCODE_05 = 0x05, VST_HOST_OPCODE_06 = 0x06, audioMasterWantMidi = 0x06, VST_HOST_OPCODE_07 = 0x07, audioMasterGetTime = 0x07, VST_HOST_OPCODE_08 = 0x08, audioMasterProcessEvents = 0x08, VST_HOST_OPCODE_09 = 0x09, // b VST_HOST_OPCODE_0A = 0x0A, audioMasterTempoAt = 0x0A, VST_HOST_OPCODE_0B = 0x0B, audioMasterGetNumAutomatableParameters = 0x0B, VST_HOST_OPCODE_0C = 0x0C, // b VST_HOST_OPCODE_0D = 0x0D, audioMasterIOChanged = 0x0D, VST_HOST_OPCODE_0E = 0x0E, audioMasterNeedIdle = 0x0E, VST_HOST_OPCODE_0F = 0x0F, audioMasterSizeWindow = 0x0F, VST_HOST_OPCODE_10 = 0x10, audioMasterGetSampleRate = 0x10, VST_HOST_OPCODE_11 = 0x11, audioMasterGetBlockSize = 0x11, VST_HOST_OPCODE_12 = 0x12, // b VST_HOST_OPCODE_13 = 0x13, // b VST_HOST_OPCODE_14 = 0x14, // b VST_HOST_OPCODE_15 = 0x15, // b VST_HOST_OPCODE_16 = 0x16, // b VST_HOST_OPCODE_17 = 0x17, audioMasterGetCurrentProcessLevel = 0x17, VST_HOST_OPCODE_18 = 0x18, audioMasterGetAutomationState = 0x18, VST_HOST_OPCODE_19 = 0x19, // b VST_HOST_OPCODE_1A = 0x1A, // b VST_HOST_OPCODE_1B = 0x1B, // b VST_HOST_OPCODE_1C = 0x1C, // b VST_HOST_OPCODE_1D = 0x1D, // b VST_HOST_OPCODE_1E = 0x1E, audioMasterSetOutputSampleRate = 0x1E, VST_HOST_OPCODE_1F = 0x1F, // b VST_HOST_OPCODE_20 = 0x20, audioMasterGetVendorString = 0x20, VST_HOST_OPCODE_21 = 0x21, audioMasterGetProductString = 0x21, VST_HOST_OPCODE_22 = 0x22, audioMasterGetVendorVersion = 0x22, VST_HOST_OPCODE_23 = 0x23, // b VST_HOST_OPCODE_24 = 0x24, // b VST_HOST_OPCODE_25 = 0x25, audioMasterCanDo = 0x25, VST_HOST_OPCODE_26 = 0x26, // b VST_HOST_OPCODE_27 = 0x27, // b VST_HOST_OPCODE_28 = 0x28, // b VST_HOST_OPCODE_29 = 0x29, audioMasterGetDirectory = 0x29, VST_HOST_OPCODE_2A = 0x2A, audioMasterUpdateDisplay = 0x2A, /* Parameter gained focus. * * @param int1 Parameter index. */ VST_HOST_OPCODE_2B = 0x2B, audioMasterBeginEdit = 0x2B, /* Parameter lost focus. * * @param int1 Parameter index. */ VST_HOST_OPCODE_2C = 0x2C, audioMasterEndEdit = 0x2C, VST_HOST_OPCODE_2D = 0x2D, VST_HOST_OPCODE_2E = 0x2E, VST_HOST_OPCODE_2F = 0x2F, // Highest number of known OPCODE. VST_HOST_OPCODE_MAX, // Cannot distinguish all these in ghidra - just assign to made up values audioMasterSetTime = 0x40, audioMasterGetParameterQuantization = 0x41, audioMasterGetInputLatency = 0x42, audioMasterGetOutputLatency = 0x43, audioMasterGetPreviousPlug = 0x44, audioMasterGetNextPlug = 0x45, audioMasterWillReplaceOrAccumulate = 0x46, audioMasterOfflineStart = 0x47, audioMasterOfflineRead = 0x48, audioMasterOfflineWrite = 0x49, audioMasterOfflineGetCurrentPass = 0x4a, audioMasterOfflineGetCurrentMetaPass = 0x4b, audioMasterGetOutputSpeakerArrangement = 0x4c, audioMasterVendorSpecific = 0x4d, audioMasterSetIcon = 0x4e, audioMasterGetLanguage = 0x4f, audioMasterOpenWindow = 0x50, audioMasterCloseWindow = 0x51, // Pad to force 32-bit number. _VST_HOST_OPCODE_PAD = 0xFFFFFFFFul, }; // ghidra enum VstSpeakerArrangementType { kSpeakerArrUserDefined = -2, kSpeakerArrEmpty = -1, kSpeakerArrMono = 0, kSpeakerArrStereo = 1, kSpeakerArrStereoSurround = 2, kSpeakerArrStereoCenter = 3, kSpeakerArrStereoSide = 4, kSpeakerArrStereoCLfe = 5, kSpeakerArr30Cine = 6, kSpeakerArr30Music = 7, kSpeakerArr31Cine = 8, kSpeakerArr31Music = 9, kSpeakerArr40Cine = 0xa, kSpeakerArr40Music = 0xb, kSpeakerArr41Cine = 0xc, kSpeakerArr41Music = 0xd, kSpeakerArr50 = 0xe, kSpeakerArr51 = 0xf, kSpeakerArr60Cine = 0x10, kSpeakerArr61Cine = 0x12, kSpeakerArr60Music = 0x11, kSpeakerArr61Music = 0x13, kSpeakerArr70Music = 0x15, kSpeakerArr70Cine = 0x14, kSpeakerArr71Music = 0x17, kSpeakerArr71Cine = 0x16, kSpeakerArr80Cine = 0x18, kSpeakerArr80Music = 0x19, kSpeakerArr81Cine = 0x1a, kSpeakerArr81Music = 0x1b, kSpeakerArr102 = 0x1c, // Pad to force 32-bit number. _VST_ARRANGEMENT_TYPE_PAD = 0xFFFFFFFFul, }; // ghidra enum VstSpeakerType { kSpeakerL = 1, kSpeakerR = 2, kSpeakerC = 3, kSpeakerLfe = 4, kSpeakerLs = 5, kSpeakerRs = 6, kSpeakerLc = 7, kSpeakerRc = 8, kSpeakerS = 9, kSpeakerSl = 10, kSpeakerSr = 11, kSpeakerTm = 12, kSpeakerTfl = 13, kSpeakerTfc = 14, kSpeakerTfr = 15, kSpeakerTrl = 16, kSpeakerTrc = 17, kSpeakerTrr = 18, kSpeakerLfe2 = 19, // Pad to force 32-bit number. _VST_SPEAKER_TYPE_PAD = 0xFFFFFFFFul, }; enum VST_PARAMETER_FLAGS { /** * Parameter is an on/off switch. */ VST_PARAMETER_FLAGS_SWITCH = 1, /** * Limits defined by integers. */ VST_PARAMETER_FLAGS_INTEGER_LIMITS = 1 << 1, /** * Uses float steps. */ VST_PARAMETER_FLAGS_STEP_FLOAT = 1 << 2, /** * Uses integer steps. */ VST_PARAMETER_FLAGS_STEP_INT = 1 << 3, /** * Respect index variable for display ordering. */ VST_PARAMETER_FLAGS_INDEX = 1 << 4, /** * Respect category value and names. */ VST_PARAMETER_FLAGS_CATEGORY = 1 << 5, VST_PARAMETER_FLAGS_UNKNOWN6 = 1 << 6, _VST_PARAMETER_FLAGS_PAD = 0xFFFFFFFFul, }; // ghidra enum VST_EVENT_TYPE { kVstMidiType = 1, kVstSysExType = 6 }; // ghidra enum VST_EFFECT_FLAGS { effFlagsHasEditor = 0x1, effFlagsCanReplacing = 0x10, effFlagsProgramChunks = 0x20, effFlagsIsSynth = 0x100, effFlagsNoSoundInStop = 0x200, effFlagsCanDoubleReplacing = 0x1000, }; // ghidra enum VstProcessPrecision { kVstProcessPrecision32 = 0, kVstProcessPrecision64 = 1 }; // ghidra enum VST_TIME_INFO_FLAGS { kVstTransportChanged = 0x1, kVstTransportPlaying = 0x2, kVstTransportCycleActive = 0x4, kVstTransportRecording = 0x8, kVstAutomationWriting = 0x40, kVstAutomationReading = 0x80, kVstNanosValid = 0x100, kVstPpqPosValid = 0x200, kVstTempoValid = 0x400, kVstBarsValid = 0x800, kVstCyclePosValid = 0x1000, kVstTimeSigValid = 0x2000, kVstSmpteValid = 0x4000, kVstClockValid = 0x8000 }; // ghidra enum VST_PIN_FLAGS { kVstPinIsActive = 0x1, kVstPinIsStereo = 0x2, kVstPinUseSpeaker = 0x4 }; // ghidra enum VstSmpteFrameRate { kVstSmpte24fps = 0, kVstSmpte25fps = 1, kVstSmpte2997fps = 2, kVstSmpte30fps = 3, kVstSmpte2997dfps = 4, kVstSmpte30dfps = 5, kVstSmpteFilm16mm = 6, kVstSmpteFilm35mm = 7, kVstSmpte239fps = 10, // why??? kVstSmpte249fps = 11, kVstSmpte599fps = 12, kVstSmpte60fps = 13, }; /******************************************************************************* |* Structures |*/ // ghidra struct VstEvent { int32_t type; int32_t byteSize; int32_t deltaFrames; int32_t flags; char data[28]; }; // ghidra struct VstMidiEvent { int32_t type; int32_t byteSize; int32_t deltaFrames; int32_t flags; int32_t noteLength; int32_t noteOffset; char midiData[4]; char detune; char noteOffVelocity; }; // ghidra struct VstMidiSysexEvent { int32_t type; int32_t byteSize; int32_t deltaFrames; int32_t flags; int32_t dumpBytes; //4 intptr_t resvd1; //8 char* sysexDump; //8 intptr_t resvd2; //8 }; // ghidra struct VstEvents { int32_t numEvents; intptr_t resvd; VstEvent* events[]; }; // ghidra struct VstTimeInfo { double samplePos; double sampleRate; double nanoSeconds; double ppqPos; double tempo; double barStartPos; double cycleStartPos; double cycleEndPos; int32_t timeSigNumerator; int32_t timeSigDenominator; int32_t smpteOffset; int32_t smpteFrameRate; int32_t _unknown; int32_t flags; }; struct ERect { int16_t top; int16_t left; int16_t bottom; int16_t right; }; // ghidra constexpr const int32_t kVstMaxVendorStrLen = 64; constexpr const int32_t kVstMaxProductStrLen = 64; // ghidra struct VstPinProperties { char label[64]; int32_t flags; int32_t arrangementType; char shortLabel[8]; char reserved[48]; }; struct AEffect { int32_t magic; // Should always be VST_MAGICNUMBER // 64-bit adds 4-byte padding here to align pointers. /* Control the VST through an opcode and up to four parameters. * * @param this Pointer to the effect itself. * @param opcode The opcode to run, see VST_EFFECT_OPCODES. * @param p_int1 Parameter, see VST_EFFECT_OPCODES. * @param p_int2 Parameter, see VST_EFFECT_OPCODES. * @param p_ptr Parameter, see VST_EFFECT_OPCODES. * @param p_float Parameter, see VST_EFFECT_OPCODES. */ intptr_t(VSTCALLBACK* dispatcher)(AEffect* pthis, int32_t opcode, int32_t p_int1, intptr_t p_int2, void* p_ptr, float p_float); /* Process the given number of samples in inputs and outputs. * * Different to process_float how? Never seen any difference. * * @param pthis Pointer to the effect itself. * @param inputs Pointer to an array of 'const float[samples]' with size numInputs. * @param outputs Pointer to an array of 'float[samples]' with size numOutputs. * @param samples Number of samples per channel in inputs. */ void(VSTCALLBACK* process)(AEffect* pthis, const float* const* inputs, float** outputs, int32_t samples); /* Updates the value for the parameter at the given index, or does nothing if out of bounds. * * @param pthis Pointer to the effect itself. * @param index Parameter index. * @param value New value for the parameter. */ void(VSTCALLBACK* setParameter)(AEffect* pthis, uint32_t index, float value); /* Returns the value stored for the parameter at index, or 0 if out of bounds. * * @param pthis Pointer to the effect itself. * @param index Parameter index. * @return float Value of the parameter. */ float(VSTCALLBACK* getParameter)(AEffect* pthis, uint32_t index); int32_t numPrograms; // Number of possible programs. int32_t numParams; // Number of possible parameters. int32_t numInputs; // Number of inputs. int32_t numOutputs; // Number of outputs. /* Bitflags * * Bit Description * 1 Effect has "Editor" * 2 Unknown (Found in: ReaDelay) * 3 Unknown (Found in: ReaDelay) * 4 Unknown (Found in: ReaDelay) * 5 Has process_float (Found in: ReaDelay, ReaComp, ReaControlMIDI, ReaStream, ReaFir) * 6 Unknown (Found in: ReaControlMIDI, ReaStream, ReaFir) * 10 Unknown (Found in: ReaFir) * 13 Has process_double (Found in: ReaControlMIDI) */ int32_t flags; // 64-bit adds 4-byte padding here to align pointers. intptr_t resvd1; intptr_t resvd2; /* Initial delay before processing of samples can actually begin in Samples. * * Should be updated before or during handling the 0x47 control call. */ int32_t initialDelay; int32_t _unknown_int32_00[2]; // Unknown int32_t values. float _unknown_float_00; // Seems to always be 1.0 void* object; // Pointer to Plugin internal data void* user; // Pointer to Host internal data. /* Id of the plugin. * * Due to this not being enough for uniqueness, it should not be used alone * for indexing. Ideally you want to index like this: * [unique_id][module_name][version][flags] * If any of the checks after unique_id fail, you default to the first * possible choice. */ int32_t uniqueID; /* Plugin version * * Unrelated to the minimum VST Version, but often the same. */ int32_t version; // There is no padding here if everything went right. /* Process the given number of single samples in inputs and outputs. * * @param pthis Pointer to the effect itself. * @param inputs Pointer to an array of 'const float[samples]' with size numInputs. * @param outputs Pointer to an array of 'float[samples]' with size numOutputs. * @param samples Number of samples per channel in inputs. */ void(VSTCALLBACK* processReplacing)(AEffect* pthis, const float* const* inputs, float** outputs, int32_t samples); /* Process the given number of double samples in inputs and outputs. * * Used only by 2.4 hosts and plugins, possibly restricted to said version. * * @param pthis Pointer to the effect itself. * @param inputs Pointer to an array of 'const double[samples]' with size numInputs. * @param outputs Pointer to an array of 'double[samples]' with size numOutputs. * @param samples Number of samples per channel in inputs. */ void(VSTCALLBACK* processDoubleReplacing)(AEffect* pthis, const double* const* inputs, double** outputs, int32_t samples); // Everything after this is unknown and was present in reacomp-standalone.dll. uint8_t _unknown[56]; // 56-bytes of something. Could also just be 52-bytes. }; struct VstParameterProperties { float step_f32; float step_small_f32; float step_large_f32; char name[VST_BUFFER_64]; uint32_t flags; int32_t min_value_i32; int32_t max_value_i32; int32_t step_i32; char label[VST_BUFFER_8]; uint16_t index; uint16_t category; uint16_t num_parameters_in_category; uint16_t _unknown_00; char category_label[VST_BUFFER_24]; char _unknown_01[VST_BUFFER_16]; }; struct VstSpeakerProperties { float _unknown_00; // 10.0 if LFE, otherwise random? Never exceeds -PI to PI range. float _unknown_04; // 10.0 if LFE, otherwise random? Never exceeds -PI to PI range. float _unknown_08; // 0.0 if LFE, otherwise 1.0. float _unknown_0C; char name[VST_BUFFER_64]; int32_t type; uint8_t _unknown[28]; // Padding detected from testing. }; struct VstSpeakerArrangement { int32_t type; int32_t numChannels; // Number of channels in speakers. VstSpeakerProperties speakers[VST_MAX_CHANNELS]; // Array of speaker properties, actual size defined by channels. }; /* Callback used by the plugin to interface with the host. * * @param opcode See VST_HOST_OPCODE * @param p_str Zero terminated string or null on call. * @return ? */ typedef intptr_t (*audioMasterCallback)(AEffect* plugin, int32_t opcode, int32_t p_int1, int64_t p_int2, const char* p_str, int32_t p_int3); static const char* vst_host_string[] = { "GetResourcePath", // ReaControlMIDI "get_ini_file", // ReaControlMIDI "resolve_fn", // ReaControlMIDI }; using VstInt32 = int32_t; /* Entry point for VST2.x plugins. * * @return A new instance of the VST2.x effect. */ #define VST_ENTRYPOINT AEffect* VSTPluginMain(vst_host_callback callback) #define VST_ENTRYPOINT_WINDOWS \ AEffect* MAIN(vst_host_callback callback) \ { \ return VSTPluginMain(callback); \ } #define VST_ENTRYPOINT_MACOS \ AEffect* main_macho(vst_host_callback callback) \ { \ return VSTPluginMain(callback); \ } #ifdef __cplusplus } #endif #pragma pack(pop) #endif