Description
The newly added resetControllers() method in SynthEngine.swift introduces a critical race condition.
Analysis
- Unsafe Access:
resetControllers() modifies voicesDX7 (via voicesDX7[i].sustained, applyPitchBend) and controller state variables (modWheelDepth, etc.).
- Concurrency Context: This method is called from
loadSlotParams, which is executed on the UI/Main thread. However, voicesDX7 and the controller variables are actively used by the render method on the high-priority Audio thread.
- Violation: This violates the single-writer principle for the audio thread resources and breaks the lock-free architecture. Accessing
UnsafeMutablePointer concurrently without locks results in undefined behavior.
Suggested Fix
Do not modify audio thread state directly from the UI thread.
- Use the existing
midiRing to send a "Reset All Controllers" message (e.g., CC 121 or a custom event).
- Handle the reset logic exclusively within
drainMIDI() or the render loop, ensuring thread locality.
Affected File
Sources/M2DXCore/Engine/SynthEngine.swift
Description
The newly added
resetControllers()method inSynthEngine.swiftintroduces a critical race condition.Analysis
resetControllers()modifiesvoicesDX7(viavoicesDX7[i].sustained,applyPitchBend) and controller state variables (modWheelDepth, etc.).loadSlotParams, which is executed on the UI/Main thread. However,voicesDX7and the controller variables are actively used by therendermethod on the high-priority Audio thread.UnsafeMutablePointerconcurrently without locks results in undefined behavior.Suggested Fix
Do not modify audio thread state directly from the UI thread.
midiRingto send a "Reset All Controllers" message (e.g., CC 121 or a custom event).drainMIDI()or the render loop, ensuring thread locality.Affected File
Sources/M2DXCore/Engine/SynthEngine.swift