4111995a5c
VST2 (Steinberg 2.4 ABI) host via Vst2Instrument: aeffect.h, dispatcher, process events/replacing, kEffectStartProcess, headless GUI skip. - create_instrument returns Vst2Instrument for InstrumentType::VST2 - 64B-aligned scratch buffers for SIMD plugins; SEH crash capture module+stack - plugins.py: VST2 resolves .dll/.so; vst_engine.py reports VST2 type - app.jsx: derive instrumentType from scan (VST3 vs VST2), not hardcoded - Install exes refreshed from Release build SF2 FluidSynth audio verified end-to-end through SHM ring (energy 1.33): silence was a test-harness bug (CC7 value written to velocity field, bridge reads data2) — app sends data2 correctly. All temporary diagnostics removed.
177 lines
6.1 KiB
C++
177 lines
6.1 KiB
C++
// native_bridge/vestige/aeffect.h
|
|
// Clean-room VST2.4 host ABI header (64-bit Windows).
|
|
//
|
|
// Written from the public VST2.4 interface specification (structure layout,
|
|
// dispatcher opcode numbers, flag bits) — NOT copied from Steinberg's SDK or
|
|
// from LMMS's vestige (LMMS is GPL-2.0+; reusing it would re-taint the bridge
|
|
// with GPL, defeating this repo's license cleanup). Only ABI facts are
|
|
// encoded here; all prose is original.
|
|
//
|
|
// A VST2 plugin is a DLL exporting `VSTPluginMain` (modern) or `main`
|
|
// (legacy): AEffect* VSTPluginMain(audioMasterCallback host).
|
|
#ifndef VESTIGE_AEFFECT_H
|
|
#define VESTIGE_AEFFECT_H
|
|
|
|
#include <cstdint>
|
|
|
|
struct AEffect; // forward decl so the callback typedefs below can reference it
|
|
|
|
// intptr_t: VST2 ABI uses pointer-sized integers on 64-bit hosts.
|
|
typedef intptr_t (*dispatcherProc)(AEffect* effect, int32_t opcode,
|
|
int32_t index, intptr_t value,
|
|
void* ptr, float opt);
|
|
typedef void (*processProc)(AEffect* effect, float** inputs, float** outputs,
|
|
int32_t sampleFrames);
|
|
typedef void (*setParameterProc)(AEffect* effect, int32_t index, float value);
|
|
typedef float (*getParameterProc)(AEffect* effect, int32_t index);
|
|
typedef void (*processReplacingProc)(AEffect* effect, float** inputs,
|
|
float** outputs, int32_t sampleFrames);
|
|
typedef void (*processDoubleReplacingProc)(AEffect* effect, double** inputs,
|
|
double** outputs,
|
|
int32_t sampleFrames);
|
|
typedef intptr_t (*audioMasterCallback)(AEffect* effect, int32_t opcode,
|
|
int32_t index, intptr_t value,
|
|
void* ptr, float opt);
|
|
|
|
struct AEffect {
|
|
int32_t magic; // 'VstP' == 0x56737450
|
|
dispatcherProc dispatcher;
|
|
processProc process;
|
|
setParameterProc setParameter;
|
|
getParameterProc getParameter;
|
|
int32_t numPrograms;
|
|
int32_t numParams;
|
|
int32_t numInputs;
|
|
int32_t numOutputs;
|
|
int32_t flags;
|
|
intptr_t resvd1; // pointer-sized per VST2.4 ABI
|
|
intptr_t resvd2;
|
|
int32_t initialDelay;
|
|
int32_t realQualities;
|
|
int32_t offQualities;
|
|
float ioRatio;
|
|
void* object;
|
|
void* user;
|
|
int32_t uniqueID;
|
|
int32_t version;
|
|
processReplacingProc processReplacing;
|
|
processDoubleReplacingProc processDoubleReplacing;
|
|
char future[56]; // reserved for future use (must stay intact)
|
|
};
|
|
|
|
// Plugin capability flag bits (AEffect::flags).
|
|
#define kEffectFlagsHasEditor (1 << 0)
|
|
#define kEffectFlagsHasClip (1 << 1)
|
|
#define kEffectFlagsHasVu (1 << 2)
|
|
#define kEffectFlagsCanMono (1 << 3)
|
|
#define kEffectFlagsCanReplacing (1 << 4)
|
|
#define kEffectFlagsProgramChunks (1 << 5)
|
|
#define kEffectFlagsIsSynth (1 << 8)
|
|
#define kEffectFlagsNoSoundInStop (1 << 9)
|
|
#define kEffectFlagsCanDoubleReplacing (1 << 12)
|
|
|
|
// Dispatcher opcodes (VST 2.4 numbering).
|
|
enum {
|
|
kEffectOpen = 0, // effOpen
|
|
kEffectClose = 1, // effClose
|
|
kEffectSetProgram = 2, // effSetProgram
|
|
kEffectGetProgram = 3, // effGetProgram
|
|
kEffectSetSampleRate = 10, // effSetSampleRate
|
|
kEffectSetBlockSize = 11, // effSetBlockSize
|
|
kEffectMainsChanged = 12, // effMainsChanged (value 1 = on, 0 = off)
|
|
kEffectGetChunk = 23, // effGetChunk
|
|
kEffectSetChunk = 24, // effSetChunk
|
|
kEffectProcessEvents = 25, // effProcessEvents
|
|
kEffectGetPlugCategory = 35,
|
|
kEffectGetEffectName = 45,
|
|
kEffectGetVendorString = 47,
|
|
kEffectGetProductString = 48,
|
|
kEffectGetVendorVersion = 49,
|
|
kEffectCanDo = 51,
|
|
kEffectGetVstVersion = 58,
|
|
kEffectStartProcess = 71,
|
|
kEffectStopProcess = 72
|
|
};
|
|
|
|
// audioMaster opcodes (host callback).
|
|
enum {
|
|
kAudioMasterAutomate = 0,
|
|
kAudioMasterVersion = 1,
|
|
kAudioMasterCurrentId = 2,
|
|
kAudioMasterIdle = 3,
|
|
kAudioMasterWantMidi = 6,
|
|
kAudioMasterGetTime = 7,
|
|
kAudioMasterProcessEvents = 8,
|
|
kAudioMasterGetSampleRate = 16,
|
|
kAudioMasterGetBlockSize = 17,
|
|
kAudioMasterGetCurrentProcessLevel = 23,
|
|
kAudioMasterGetVendorString = 32,
|
|
kAudioMasterGetProductString = 33,
|
|
kAudioMasterGetVendorVersion = 34,
|
|
kAudioMasterVendorSpecific = 35,
|
|
kAudioMasterCanDo = 37,
|
|
kAudioMasterGetLanguage = 38
|
|
};
|
|
|
|
// MIDI event passed via effProcessEvents. The plugin receives a VstEvents
|
|
// array; each event starts with a VstEvent header, VstMidiEvent extends it.
|
|
struct VstEvent {
|
|
int32_t type; // kVstMidiType == 1 for MIDI events
|
|
int32_t byteSize; // sizeof(VstMidiEvent)
|
|
int32_t deltaFrames;
|
|
int32_t flags;
|
|
};
|
|
|
|
struct VstMidiEvent {
|
|
int32_t type; // kVstMidiType == 1
|
|
int32_t byteSize; // sizeof(VstMidiEvent)
|
|
int32_t deltaFrames;
|
|
int32_t flags;
|
|
int32_t noteLength; // in sample frames, if available, else 0
|
|
int32_t noteOffset; // offset into note, if available, else 0
|
|
char midiData[4]; // 1-3 MIDI bytes; midiData[3] reserved (zero)
|
|
char detune; // -64..+63 cents
|
|
char noteOffVelocity;
|
|
char reserved1;
|
|
char reserved2;
|
|
};
|
|
|
|
struct VstEvents {
|
|
int32_t numEvents;
|
|
intptr_t reserved;
|
|
VstEvent* events[2];
|
|
};
|
|
|
|
// Time info returned to kAudioMasterGetTime (host fills this).
|
|
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 samplesToNextClock;
|
|
int32_t flags;
|
|
};
|
|
|
|
#define kVstMidiType 1
|
|
#define kEffectMagic 0x56737450 // 'VstP'
|
|
|
|
// VstTimeInfo::flags bits (kAudioMasterGetTime).
|
|
#define kVstTransportPlaying 1
|
|
#define kVstTransportCycleActive 2
|
|
#define kVstTransportChanged 4
|
|
#define kVstTempoValid 8
|
|
|
|
// Host responses for the plugin's capability probes (kEffectCanDo).
|
|
#define kCanDoYes 1
|
|
#define kCanDoNo 0
|
|
|
|
#endif // VESTIGE_AEFFECT_H
|