mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-22 21:01:40 +00:00
fix(input_setup): correct meter lifecycle on device-change + concurrent Test-input
Capture the pre-preview detection state once (not per reopen) so the wizard restores detect on/off correctly after a device change; add a generation guard so overlapping startTest() runs from rapid changes can't interleave enable/disable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
db0b55a301
commit
4df69beeaf
@ -186,8 +186,11 @@
|
||||
const SIGNAL_THRESHOLD = 0.04;
|
||||
let pollTimer = null;
|
||||
let testing = false;
|
||||
let weEnabled = false; // did WE turn detection on (so we restore it)?
|
||||
// Detection on/off BEFORE we first opened the preview — captured once,
|
||||
// so we restore it on exit even after device-change reopens.
|
||||
let preTestEnabled = null;
|
||||
let handingOff = false; // Calibrate owns the capture from here on
|
||||
let testGen = 0; // invalidate in-flight startTest()s on change/exit
|
||||
|
||||
function stopPoll() { if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } }
|
||||
function resetGate() {
|
||||
@ -215,6 +218,7 @@
|
||||
}, 100);
|
||||
}
|
||||
async function startTest() {
|
||||
const myGen = ++testGen; // a newer change/exit supersedes us
|
||||
stopPoll();
|
||||
resetGate();
|
||||
if (meterWrap) meterWrap.classList.remove('hidden');
|
||||
@ -223,10 +227,15 @@
|
||||
// must cycle disable→enable or the meter would read the stale
|
||||
// device — false confidence, the exact bug this gate prevents.
|
||||
await commitAudio(sel.value);
|
||||
if (myGen !== testGen) return;
|
||||
try {
|
||||
if (nd.isEnabled()) { await nd.disable(); await nd.enable(); weEnabled = false; }
|
||||
else { await nd.enable(); weEnabled = true; }
|
||||
// Capture the pre-preview detection state ONCE so we restore it
|
||||
// on exit (a later reopen must not lose that we own the enable).
|
||||
if (preTestEnabled === null) preTestEnabled = !!nd.isEnabled();
|
||||
if (nd.isEnabled()) { await nd.disable(); if (myGen !== testGen) return; }
|
||||
await nd.enable();
|
||||
} catch (_) { /* fail-soft: meter just won't move; Calibrate still works */ }
|
||||
if (myGen !== testGen) return;
|
||||
testing = true;
|
||||
startPoll();
|
||||
}
|
||||
@ -251,8 +260,10 @@
|
||||
_activeCleanup = () => {
|
||||
stopPoll();
|
||||
testing = false;
|
||||
if (weEnabled && !handingOff) { try { nd.disable(); } catch (_) {} }
|
||||
weEnabled = false;
|
||||
testGen++; // cancel any in-flight startTest()
|
||||
// Restore the pre-preview detection state unless the Calibration
|
||||
// Wizard has taken ownership of the capture.
|
||||
if (preTestEnabled === false && !handingOff) { try { nd.disable(); } catch (_) {} }
|
||||
};
|
||||
|
||||
// Tell the tuner tables / note_detect which instrument this is.
|
||||
@ -264,6 +275,7 @@
|
||||
// cleanup must not disable detection out from under it.
|
||||
handingOff = true;
|
||||
stopPoll();
|
||||
testGen++; // cancel any in-flight startTest() before handoff
|
||||
if (hasDetector) {
|
||||
// Hide our own full-screen overlay while note_detect's
|
||||
// Calibration Wizard runs on top. That wizard goes
|
||||
@ -286,11 +298,9 @@
|
||||
onCancel: () => {
|
||||
restore();
|
||||
// Back on this panel: reclaim cleanup ownership so a
|
||||
// later Skip/Continue still restores detection state.
|
||||
// The wizard's enable() may have left detection on; if
|
||||
// we didn't turn it on ourselves, leave it as-is.
|
||||
// later Skip/Continue still restores the pre-preview
|
||||
// detection state (preTestEnabled is unchanged).
|
||||
handingOff = false;
|
||||
if (nd && typeof nd.isEnabled === 'function') { try { weEnabled = weEnabled && nd.isEnabled(); } catch (_) {} }
|
||||
},
|
||||
});
|
||||
} else {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user