editor: MIDI 'Device audio' diagnostics (show device name + pulse on note)
User reported no computer audio + 'no device being controlled'. Add visibility to diagnose: the button now shows the connected MIDI input's name (or 'no device'), the toggle alert lists detected inputs, and the button pulses green on each Note-On received — so it's clear whether the device is seen and whether notes are arriving. Also call ensureAudio() in the message handler as a guard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8433c5bfe2
commit
aaf5c4d260
1 changed files with 17 additions and 7 deletions
24
editor.html
24
editor.html
|
|
@ -1117,25 +1117,35 @@ async function loadFromDevice() {
|
|||
|
||||
/* Device audio (Phase 3): a connected PM_K-1 sends a USB-MIDI note per click; we voice it through
|
||||
this page's synth, so the device drives sound out the computer's speakers, locked to its clock. */
|
||||
let _midiAccess = null, _midiOn = false;
|
||||
let _midiAccess = null, _midiOn = false, _midiFlash = 0;
|
||||
function _midiInputs() { return _midiAccess ? [..._midiAccess.inputs.values()] : []; }
|
||||
function onDeviceMidi(e) {
|
||||
const d = e.data; if (!d || d.length < 3) return;
|
||||
if ((d[0] & 0xf0) === 0x90 && d[2] > 0) { // Note On
|
||||
const v = d[2], gain = v >= 110 ? 1.0 : v >= 70 ? 0.6 : 0.25; // accent / normal / ghost
|
||||
try { playInstrument(GM_NUM[d[1]] || "beep", audioCtx.currentTime, gain); } catch (_) {}
|
||||
try { ensureAudio(); playInstrument(GM_NUM[d[1]] || "beep", audioCtx.currentTime, gain); } catch (_) {}
|
||||
const b = $("midiBtn"); if (b) { b.style.boxShadow = "0 0 0 2px #2fe07a"; clearTimeout(_midiFlash); _midiFlash = setTimeout(() => b.style.boxShadow = "", 90); }
|
||||
}
|
||||
}
|
||||
function _bindMidi() { if (_midiAccess) for (const inp of _midiAccess.inputs.values()) inp.onmidimessage = _midiOn ? onDeviceMidi : null; }
|
||||
function updateMidiBtn() { const b = $("midiBtn"); if (b) { b.textContent = _midiOn ? "🎹 Device audio: ON" : "🎹 Device audio"; b.classList.toggle("primary", _midiOn); } }
|
||||
function _bindMidi() { for (const inp of _midiInputs()) inp.onmidimessage = _midiOn ? onDeviceMidi : null; }
|
||||
function updateMidiBtn() {
|
||||
const b = $("midiBtn"); if (!b) return;
|
||||
if (!_midiOn) { b.textContent = "🎹 Device audio"; b.classList.remove("primary"); b.style.boxShadow = ""; return; }
|
||||
const names = _midiInputs().map((i) => i.name || "MIDI");
|
||||
b.textContent = names.length ? "🎹 " + names[0].slice(0, 16) : "🎹 no device"; // shows the connected MIDI device
|
||||
b.classList.add("primary");
|
||||
}
|
||||
async function toggleDeviceAudio() {
|
||||
if (_midiOn) { _midiOn = false; _bindMidi(); updateMidiBtn(); return; }
|
||||
if (!navigator.requestMIDIAccess) return alert("Playing the device through this computer needs the Web MIDI API — use Chrome or Edge.");
|
||||
try { if (!_midiAccess) { _midiAccess = await navigator.requestMIDIAccess(); _midiAccess.onstatechange = _bindMidi; } }
|
||||
try { if (!_midiAccess) { _midiAccess = await navigator.requestMIDIAccess(); _midiAccess.onstatechange = () => { _bindMidi(); updateMidiBtn(); }; } }
|
||||
catch (e) { return alert("MIDI access was denied."); }
|
||||
ensureAudio(); if (audioCtx && audioCtx.state === "suspended") audioCtx.resume();
|
||||
_midiOn = true; _bindMidi(); updateMidiBtn();
|
||||
if (![..._midiAccess.inputs.values()].length)
|
||||
alert("No MIDI device detected yet — plug in the PM_K-1 (CircuitPython firmware) and press play on it. (It stays armed; new devices connect automatically.)");
|
||||
const names = _midiInputs().map((i) => i.name || "MIDI");
|
||||
alert(names.length
|
||||
? "Device audio ON.\nMIDI input(s): " + names.join(", ") + "\nPress play on the device — the button pulses green on each note received."
|
||||
: "Device audio is armed, but NO MIDI input is connected.\nPlug in the PM_K-1 running the CircuitPython firmware — it should appear here as a MIDI device. (New devices connect automatically.)");
|
||||
}
|
||||
|
||||
// Apply a shared link on load. Returns true if it set the metronome state.
|
||||
|
|
|
|||
Loading…
Reference in a new issue