195 lines
5.7 KiB
C++
195 lines
5.7 KiB
C++
// 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 <cstdint>
|
|
#include <stdint.h>
|
|
|
|
#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);
|