G4.3: double-buffer sandbox SHM - SandboxHostIPC writeSlot+2x256 double audio, latency 15.6ms, multi-instance no-xrun verified

This commit is contained in:
2026-08-16 11:35:31 +07:00
parent 462a5104d2
commit 9436e66835
8 changed files with 64 additions and 26 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ private:
uint32_t block_ = AUDIO_BLOCK_SIZE;
uint32_t channel_ = 0;
ShmHandle* shm_ = nullptr;
SharedAudioBufferIPC* ipc_ = nullptr;
SandboxHostIPC* ipc_ = nullptr;
std::atomic<bool> alive_{false};
std::atomic<bool> stop_{false};
std::thread watchdog_;
+15 -2
View File
@@ -1,6 +1,7 @@
// native_bridge/include/SharedMemoryIPC.h
#pragma once
#include <cstdint>
#include <cstddef>
#ifdef _WIN32
#include <windows.h>
@@ -63,11 +64,23 @@ struct SharedAudioBufferIPC {
volatile uint32_t heartbeat;
};
// G4.3: per-plugin sandbox SHM — double-buffered audio handoff.
// The child renders into the slot it is NOT publishing (writeSlot flips),
// then publishes; the bridge reads the published slot. A stale slot is safe
// to read (bridge keeps last block), so a slow child never tears audio.
struct SandboxHostIPC {
SharedAudioBufferIPC base; // MIDI/control/heartbeat, offsets unchanged
volatile uint32_t writeSlot; // 0 or 1: slot the child finished writing
float audioLeft[2][AUDIO_BLOCK_SIZE]; // 2 full blocks
float audioRight[2][AUDIO_BLOCK_SIZE];
};
// Shared-memory helpers (impl in SharedMemoryIPC.cpp).
struct ShmHandle;
ShmHandle* shm_open(const char* name);
ShmHandle* shm_create(const char* name);
ShmHandle* shm_open(const char* name, size_t size = sizeof(SharedAudioBufferIPC));
ShmHandle* shm_create(const char* name, size_t size = sizeof(SharedAudioBufferIPC));
SharedAudioBufferIPC* shm_ptr(ShmHandle* h);
SandboxHostIPC* shm_sandbox_ptr(ShmHandle* h);
void shm_close(ShmHandle* h);
bool shm_write_midi(ShmHandle* h, uint8_t cmd, uint8_t channel, uint8_t pitch,
uint8_t velocity, uint32_t sampleOffset, uint8_t data2 = 0,