What happened?
On Windows, opening and closing complex VST3 plugin GUI editors (e.g., Tokyo Dawn Records TDR Nova) causes direct instability:
- The plugin window either freezes or turns completely black after a short moment.
- Closing the plugin editor or stopping the audio pipeline triggers an immediate application crash (
0xC0000005 Access Violation in ntdll.dll).
Root Cause Analysis
Running VST3 editors in-process alongside Tauri 2 (WebView2 / Tao event loop) triggers core platform conflicts:
- Event Loop Interference: Tao and WebView2 capture the Windows message loop, starving JUCE-based plugins of standard
WM_TIMER dispatching needed for rendering and UI state updates.
- Heap & COM Collisions: Destructing plugin resources during slot recycling or pipeline teardown conflicts with WebView2's DirectComposition and heap allocator (
RtlpFreeHeap).
- Threading Deadlocks: JUCE binds GUI initialization to the main thread; off-thread calls freeze on
juce::MessageManagerLock.
Steps to reproduce
- Launch Splitwave on Windows.
- Add an audio source and insert a complex VST3 plugin node (e.g., TDR Nova).
- Open the plugin GUI editor window.
- Observe the interface freezing or blacking out after initial render.
- Close the plugin editor window or stop the audio pipeline/remove the node.
Expected behavior
The VST3 GUI editor should render continuously at 60 fps without freezing, and closing the editor or stopping/reconfiguring the audio pipeline should not crash the host process.
App version
v1.1.0
Operating system
Windows
OS version
25H2
Additional context
Proposed Solution: Out-of-Process Plugin Bridge
To eliminate crashes and provide a clean 60 fps Win32 rendering environment, I developed an Out-of-Process hosting architecture for Windows:
- Dedicated Helper: Minimal runner spawned via
splitwave.exe --plugin-bridge <session_id> running a pure Win32 message loop without any webview overhead.
- Low-Latency Audio IPC: SPSC ring buffer communication across Windows Shared Memory (
CreateFileMappingW / MapViewOfFile) with atomic sequence tracking (<0.1 ms latency).
- Control Channel: Thread-safe synchronization for parameter automation, state sync, and window toggle (
SW_HIDE / SW_SHOW).
- View Lifecycle Safety: Safe
IPlugView caching (take_view) preventing use-after-free conditions during editor probing.
Scope of Changes
src-tauri/src/audio/plugins/bridge/: Bridge runner, shared memory audio IPC, and messaging protocol (#[cfg(target_os = "windows")]).
src-tauri/src/audio/plugins/vst3_host.rs: Safe IPlugView handling.
src-tauri/src/audio/plugins/registry.rs: Dispatch Windows VST3 nodes to BridgeHost.
src-tauri/src/main.rs: Early command-line dispatch for --plugin-bridge prior to webview init.
src-tauri/Cargo.toml: Enable Win32_System_Memory Windows sys features.
Verification
- Tested on Windows 11 with TDR Nova.
- Confirmed stable real-time spectrum drawing at 60 fps, zero-latency parameter updates, and crash-free pipeline stops.
- Non-Windows platforms remain completely unaffected.
I have already implemented and verified this solution locally. If this approach fits the project architecture, I can submit the Pull Request for review.
What happened?
On Windows, opening and closing complex VST3 plugin GUI editors (e.g., Tokyo Dawn Records TDR Nova) causes direct instability:
0xC0000005Access Violation inntdll.dll).Root Cause Analysis
Running VST3 editors in-process alongside Tauri 2 (WebView2 / Tao event loop) triggers core platform conflicts:
WM_TIMERdispatching needed for rendering and UI state updates.RtlpFreeHeap).juce::MessageManagerLock.Steps to reproduce
Expected behavior
The VST3 GUI editor should render continuously at 60 fps without freezing, and closing the editor or stopping/reconfiguring the audio pipeline should not crash the host process.
App version
v1.1.0
Operating system
Windows
OS version
25H2
Additional context
Proposed Solution: Out-of-Process Plugin Bridge
To eliminate crashes and provide a clean 60 fps Win32 rendering environment, I developed an Out-of-Process hosting architecture for Windows:
splitwave.exe --plugin-bridge <session_id>running a pure Win32 message loop without any webview overhead.CreateFileMappingW/MapViewOfFile) with atomic sequence tracking (<0.1 ms latency).SW_HIDE/SW_SHOW).IPlugViewcaching (take_view) preventing use-after-free conditions during editor probing.Scope of Changes
src-tauri/src/audio/plugins/bridge/: Bridge runner, shared memory audio IPC, and messaging protocol (#[cfg(target_os = "windows")]).src-tauri/src/audio/plugins/vst3_host.rs: SafeIPlugViewhandling.src-tauri/src/audio/plugins/registry.rs: Dispatch Windows VST3 nodes toBridgeHost.src-tauri/src/main.rs: Early command-line dispatch for--plugin-bridgeprior to webview init.src-tauri/Cargo.toml: EnableWin32_System_MemoryWindows sys features.Verification
I have already implemented and verified this solution locally. If this approach fits the project architecture, I can submit the Pull Request for review.