diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index c2c08c07d..859c54f9b 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -499,13 +499,16 @@ class MidiInput { const midiListener = this._onMidiMessage.bind(this); device.addListener('midimessage', midiListener); + + this._loadAllStates(); + + const output = WebMidi.outputs.find((o) => o.name === this.name); + if (output) { + this._sendAllStates(output); + } } createCC(cc, chan) { - if (chan !== undefined && !(chan in this._refsByChan)) { - this._refsByChan[chan] = {}; - } - const lookupMap = chan === undefined ? this._refs : this._refsByChan[chan]; if (!(cc in lookupMap)) { const initialState = this._loadState(chan); @@ -529,6 +532,15 @@ class MidiInput { this._saveState(chan, ccNum, scaled); } + _loadAllStates() { + Object.assign(this._refs, this._loadState(undefined)); + + for (let chan = 1; chan <= 16; chan++) { + this._refsByChan[chan] ??= {}; + Object.assign(this._refsByChan[chan], this._loadState(chan)); + } + } + _loadState(chan) { const initialDataRaw = localStorage.getItem(`strudel-midin-${this.name}-chan${chan !== undefined ? chan : 'all'}`); if (!initialDataRaw) { @@ -552,6 +564,17 @@ class MidiInput { state[cc] = value; localStorage.setItem(`strudel-midin-${this.name}-chan${chan !== undefined ? chan : 'all'}`, JSON.stringify(state)); } + + _sendAllStates(output) { + for (const [chan, refs] of Object.entries(this._refsByChan)) { + const channel = Number(chan); + for (const [cc, value] of Object.entries(refs)) { + const ccn = Number(cc); + const scaled = Math.round(value * 127); + output.sendControlChange(ccn, scaled, channel); + } + } + } } // MIDI input wrappers, by device ID