fix(playground): decouple MIDIInput from C15Bridge — use SynthEngine interface (meml-se4)

This commit is contained in:
w1n5t0n 2026-04-03 18:20:29 +01:00
parent 5a004c6a3e
commit 3c44b75416
2 changed files with 11 additions and 7 deletions

View file

@ -810,6 +810,7 @@ async function setActiveEngine(engine) {
activeEngine = engine;
c15 = engine; // keep alias in sync
arpeggiator.setEngine(engine);
if (midiInput) midiInput.setEngine(engine);
const btn = document.getElementById('synth-mode-btn');
if (btn) btn.textContent = engine.displayName;
const engineDockBtn = document.querySelector('[data-drawer="params"]');
@ -916,7 +917,7 @@ async function init() {
if (el) el.textContent = msg;
};
arpeggiator = new Arpeggiator(activeEngine);
midiInput = new MIDIInput(activeEngine.bridge); // MIDIInput still talks to the C15 bridge directly
midiInput = new MIDIInput(activeEngine);
initMIDIControls();
// MIDI Output

View file

@ -1,9 +1,9 @@
// MIDI Input — receives notes and CCs from external MIDI controllers
// Uses Web MIDI API, routes note on/off to C15 bridge
// Uses Web MIDI API, routes note on/off through a SynthEngine interface
export class MIDIInput {
constructor(bridge) {
this.bridge = bridge;
constructor(engine) {
this.engine = engine;
this.enabled = false;
this.midiAccess = null;
this.selectedInputId = null;
@ -19,6 +19,9 @@ export class MIDIInput {
set onInputsChange(fn) { this._onInputsChange = fn; }
set onCC(fn) { this._onCC = fn; }
/** Hot-swap the engine (e.g. when the user switches synth engines). */
setEngine(engine) { this.engine = engine; }
_status(msg) {
console.log('[MIDI]', msg);
this._onStatusChange?.(msg);
@ -130,15 +133,15 @@ export class MIDIInput {
switch (type) {
case 0x90: // Note On
if (data2 > 0) {
this.bridge.noteOn(data1, data2 / 127);
this.engine.noteOn(data1, data2 / 127);
} else {
// Velocity 0 = note off
this.bridge.noteOff(data1);
this.engine.noteOff(data1);
}
break;
case 0x80: // Note Off
this.bridge.noteOff(data1);
this.engine.noteOff(data1);
break;
case 0xb0: // Control Change