wip(nexus): debug crash 0xc000041d khi mở GUI Nexus — lưu trạng thái điều tra (attached() hang; probe exact11 PASS, bridge hang; g_engine hypothesis disproven; chờ phân tích waitscan wait-object)
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -72,6 +73,19 @@ public:
|
||||
|
||||
INativeInstrument* get(uint32_t channel);
|
||||
|
||||
// Real-time MIDI dispatch (audio loop thread). Each call holds mu_ for the
|
||||
// WHOLE call — lookup + reloading check + instrument call under one lock —
|
||||
// so a worker thread's assign()/unload() can never swap the map and destroy
|
||||
// the old instance while dispatch is inside a method on it (use-after-free
|
||||
// when loading a new VSTi while others play). Events for unassigned or
|
||||
// reloading channels are dropped (a mid-reload instance must not be touched
|
||||
// while its worker rebuilds state_ in place).
|
||||
void noteOn(uint32_t channel, uint32_t pitch, float velocity);
|
||||
void noteOff(uint32_t channel, uint32_t pitch);
|
||||
void controlChange(uint32_t channel, uint32_t cc, uint32_t value);
|
||||
void programChange(uint32_t channel, uint32_t program);
|
||||
void pitchBend(uint32_t channel, uint32_t bend14);
|
||||
|
||||
// Remove and destroy the instrument on `channel` (its destructor may call
|
||||
// VST terminate — MUST run on the channel worker thread, caller's duty).
|
||||
// Used by Option B: two live instances of the same plugin DLL (Nexus)
|
||||
@@ -87,6 +101,16 @@ public:
|
||||
// teardown never races the audio thread.
|
||||
void setReloading(uint32_t channel, bool on);
|
||||
|
||||
// True while a channel is being rebuilt (instance teardown/reload on its
|
||||
// worker thread): real-time code drops MIDI for it. Channel-level flag —
|
||||
// survives the instance swap (the per-instance flag dies with the object).
|
||||
bool isReloading(uint32_t channel) const;
|
||||
// Editor-open predicate: while any VST editor is attached, channels whose
|
||||
// plugin DLL path has an open editor count as quiet (same-plugin channels
|
||||
// too -- the worker pumps the editor's window proc inside the DLL while the
|
||||
// audio loop process()es other instances of the same DLL).
|
||||
void setEditorOpenPredicate(std::function<bool(const std::string& lowerPath)> fn);
|
||||
|
||||
// Flush every sounding note on every assigned channel.
|
||||
void allNotesOff();
|
||||
|
||||
@@ -103,6 +127,13 @@ private:
|
||||
std::map<uint32_t, std::string> paths_; // last assigned path per channel
|
||||
// Per-instrument scratch so engines that overwrite (not mix) stay additive.
|
||||
std::vector<float> scratchL_, scratchR_;
|
||||
// Channel-level reload flag (see isReloading) — indexed by MIDI channel.
|
||||
bool reloadingCh_[16] = {};
|
||||
// True when the channel's plugin DLL has an attached editor (or its reload
|
||||
// is in progress): real-time code drops MIDI and skips rendering. Lowercased
|
||||
// compare inside -- Windows plugin paths are case-insensitive.
|
||||
bool channelQuiet(uint32_t ch) const;
|
||||
std::function<bool(const std::string&)> editorOpenFn_;
|
||||
};
|
||||
|
||||
#endif // NATIVE_INSTRUMENT_ENGINE_H
|
||||
|
||||
Reference in New Issue
Block a user