// vestige.h — clean-room VST2 (AEffect) API header (T10, spec 5.7 / spec III) // // QUYẾT ĐỊNH (T10): KHÔNG dùng aeffect.h/aeffectx.h chính thức (Steinberg // ngừng license VST2 10/2018 — spec III). Viết lại từ kiến thức public của // giao diện AEffect: struct + opcode enum đủ cho host (load, MIDI, GUI, // processReplacing). Chỉ giữ phần host cần — không phải bản sao SDK. // // Nâng cấp nếu cần: thay bằng bridge có sẵn (Carla/Wine-VST) hoặc gộp JUCE. #pragma once #include #include #define VSTCALLBACK __cdecl #ifdef _WIN32 #define CCONST(a, b, c, d) ((int32)((d) << 24 | (c) << 16 | (b) << 8 | (a))) #else #define CCONST(a, b, c, d) ((int32)((a) << 24 | (b) << 16 | (c) << 8 | (d))) #endif typedef int32_t int32; typedef intptr_t VstIntPtr; typedef float VstParamValue; //------------------------------------------------------------------------ // AEffect — layout công khai của VST2; KHÔNG đổi thứ tự field. struct AEffect { int32 magic; // kEffectMagic = CCONST('V', 's', 't', 'P') int32 (VSTCALLBACK* dispatcher)(AEffect*, int32 opcode, int32 index, VstIntPtr value, void* ptr, float opt); void (VSTCALLBACK* process)(AEffect*, float** inputs, float** outputs, int32 sampleFrames); void (VSTCALLBACK* setParameter)(AEffect*, int32 index, float parameter); float (VSTCALLBACK* getParameter)(AEffect*, int32 index); int32 (VSTCALLBACK* numPrograms)(AEffect*); int32 (VSTCALLBACK* numParams)(AEffect*); int32 (VSTCALLBACK* numInputs)(AEffect*); int32 (VSTCALLBACK* numOutputs)(AEffect*); int32 (VSTCALLBACK* flags)(AEffect*); int32 resvd1; int32 resvd2; int32 initialDelay; int32 realQualities; int32 offQualities; float ioRatio; void* object; void* user; int32 uniqueID; int32 version; void (VSTCALLBACK* processReplacing)(AEffect*, float** inputs, float** outputs, int32 sampleFrames); void (VSTCALLBACK* processDoubleReplacing)(AEffect*, double** inputs, double** outputs, int32 sampleFrames); }; enum VstAEffectFlags { effFlagsHasEditor = 1 << 0, effFlagsCanReplacing = 1 << 4, effFlagsProgramChunks = 1 << 5, effFlagsIsSynth = 1 << 8, effFlagsNoSoundInStop = 1 << 9, effFlagsCanDoubleReplacing = 1 << 12 }; //------------------------------------------------------------------------ // Dispatcher opcodes (host -> plugin) enum VstEffectOpcodes { effOpen = 0, effClose = 1, effSetProgram = 2, effGetProgram = 3, effSetProgramName = 4, effGetProgramName = 5, effGetParamLabel = 6, effGetParamDisplay = 7, effGetParamName = 8, effSetSampleRate = 10, effSetBlockSize = 11, effMainsChanged = 12, effEditGetRect = 13, effEditOpen = 14, effEditClose = 15, effEditIdle = 19, effEditTop = 20, effEditSleep = 21, effIdentify = 22, effGetChunk = 23, effSetChunk = 24, effProcessEvents = 25, effCanBeAutomated = 26, effGetEffectName = 39, effGetVendorString = 41, effGetProductString = 42, effGetVendorVersion = 43, effCanDo = 45, effIdle = 47, effSetViewPosition = 49, effGetVstVersion = 52, effEditKeyDown = 53, effEditKeyUp = 54, effStartProcess = 65, effStopProcess = 66, effSetProcessPrecision = 71 }; enum VstPluginCanDo { canDoSendVstEvents = 0, canDoSendVstMidiEvent = 1, canDoReceiveVstEvents = 2, canDoReceiveVstMidiEvent = 3 }; //------------------------------------------------------------------------ // AudioMasterCallback opcodes (plugin -> host) enum VstAudioMasterOpcodes { audioMasterAutomate = 0, audioMasterVersion = 1, audioMasterCurrentId = 2, audioMasterIdle = 3, audioMasterWantMidi = 6, audioMasterGetTime = 7, audioMasterProcessEvents = 8, audioMasterGetVendorString = 14, audioMasterGetProductString = 15, audioMasterGetVendorVersion = 16, audioMasterCanDo = 19, audioMasterGetLanguage = 20, audioMasterGetDirectory = 21, audioMasterUpdateDisplay = 22, audioMasterGetSampleRate = 35, audioMasterGetBlockSize = 36, audioMasterGetInputLatency = 29, audioMasterGetOutputLatency = 30 }; //------------------------------------------------------------------------ // MIDI events qua effProcessEvents (không dùng giao diện MIDI cũ của AEffect) struct VstEvent { int32 type; int32 byteSize; int32 flags; intptr_t* data; // 4 bytes padding trên Win64 giữ layout }; struct VstMidiEvent { int32 type; // kVstMidiType int32 byteSize; // sizeof(VstMidiEvent) int32 deltaFrames; int32 flags; // kVstMidiEventIsRealtime int32 noteLength; // 0 int32 noteOffset; // 0 char midiData[4]; // status, data1, data2, pad char detune; char noteOffVelocity; char reserved1; char reserved2; }; struct VstEvents { int32 numEvents; intptr_t reserved; VstEvent* events[1]; }; enum VstEventTypes { kVstMidiType = 1 }; enum VstMidiEventFlags { kVstMidiEventIsRealtime = 1 << 0 }; //------------------------------------------------------------------------ // Editor rect (effEditGetRect) struct ERect { short top; short left; short bottom; short right; }; //------------------------------------------------------------------------ // VST2 entry points (typedef names khác tên export để tránh redefinition) typedef AEffect* (VSTCALLBACK* VSTPluginMainFn)(void* audioMasterCallback); typedef AEffect* (VSTCALLBACK* VSTPluginMainOldFn)(void* audioMasterCallback, void* reserved); typedef VstIntPtr (VSTCALLBACK* audioMasterCallbackFunc)(AEffect* effect, int32 opcode, int32 index, VstIntPtr value, void* ptr, float opt);