Files
SonicForgeStudio/native_bridge/include/SharedMemoryIPC.h
T
admin d8f8506077 fix: GUI VST native window qua bridge + audio path bridge (SF2 preview/play câm)
- open_vst_gui: bo WebviewWindowBuilder/thread, chi push_control type=4 (hwnd=0 -> bridge tao window)
- main.cpp: create_native_vst_window (class SonicForge_Native_VST3_Class, 800x600, khong TOPMOST),
  tao trong ChannelWorker job, map guiWindows, capture arg2 by value (fix dangling)
- app.jsx: guard isBridgeActive() 8 cho -> bridge active thi moi note di router -> pushEvent -> bridge
  (truoc day SF2 cam vi HAS_PYFLUIDSYNTH=FALSE -> /soundfont-render 501; VST3 path cu dung nativeSf/Carla)
- E2E: SF2 NOTE_ON qua dispatchMidiEvent -> SHM peak 0.029745; Nexus GUI native hwnd OK (license/preset)
- docs: TASKS.md + TEST_NOTES.md ghi batch fix + ket qua; gitignore vendor/junk
2026-08-12 22:12:43 +07:00

53 lines
2.1 KiB
C++

// native_bridge/include/SharedMemoryIPC.h
#pragma once
#include <cstdint>
#ifdef _WIN32
#include <windows.h>
#endif
#define AUDIO_BLOCK_SIZE 256
// WARNING: volatile is NOT a sync primitive. Real impl should use an
// interlocked/index-flag pair or a Win32 event (SetEvent) signalled by the
// writer. This struct follows the spec layout so Rust/JS mapping stays in sync.
struct SharedAudioBufferIPC {
// Synchronization Flags
volatile uint32_t clientReadIndex;
volatile uint32_t bridgeWriteIndex;
// PCM Float32 Audio Buffers
float masterLeft[AUDIO_BLOCK_SIZE];
float masterRight[AUDIO_BLOCK_SIZE];
// Latency probe: bridge stamps every rendered block (QueryPerformanceCounter)
volatile uint64_t blockTimestamp;
// MIDI Event Exchange Queue
struct MidiEventIPC {
uint8_t command; // 0x9 note on / 0x8 note off / 0xB CC / 0xC program / 0xE pitch bend
uint8_t channel;
uint8_t pitch; // note number (0x9/0x8) or CC number (0xB)
uint8_t velocity; // 0-127 (0x9 + vel=0 == note off)
uint8_t data2; // CC value / program number / PB LSB
uint8_t data3; // PB MSB (0xE only)
uint8_t reserved[2]; // explicit padding — keeps C/Rust layout stable
uint32_t sampleOffset;
} midiQueue[64];
volatile uint32_t midiQueueCount;
// Transport / Control (added vs spec: Stop/Play flush, instrument switch)
struct ControlEventIPC {
uint32_t type; // 0 = NONE, 1 = PANIC/ALL_NOTES_OFF, 2 = LOAD_INSTRUMENT,
// 3 = TRANSPORT, 4 = OPEN_GUI
uint32_t arg0; // LOAD: instrument type (InstrumentType);
// TRANSPORT: 0=STOP, 1=PLAY, 2=SET_POSITION
uint32_t arg1; // LOAD: string length (bytes) of path;
// TRANSPORT: playheadSamples (for timeline sync)
uint32_t channel; // LOAD: MIDI channel to assign instrument to (A10)
char arg2[1024]; // LOAD: UTF-8 path
} controlQueue[8];
volatile uint32_t controlQueueCount;
};