diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 677a667..e0188e6 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -6757,11 +6757,14 @@ const App = () => { setLastMidiNote({ pitch, velocity, length: 0, time: Date.now() }); activeMidiPitchesRef.current.add(pitch); setActiveMidiPitches(new Set(activeMidiPitchesRef.current)); - // Stop previous notes on this channel before playing new note - { if (window.SonicSF) { - const ch = msg.data[0] & 0x0F; - try { window.SonicSF.controllerChange(ch, 123, 0); } catch (e) {} - const arSub = subTabsRef && subTabsRef.current && activeTabRef && subTabsRef.current.find(s => s.id === activeTabRef.current && s.type === 'PIANO_ROLL' && s.isArmed); + // Stop previous notes on this channel before playing new note + // Only send All Notes Off when sustain pedal is not active + { if (window.SonicSF) { + const ch = msg.data[0] & 0x0F; + if (!window.SonicSF.sustainActive || !window.SonicSF.sustainActive(ch)) { + try { window.SonicSF.controllerChange(ch, 123, 0); } catch (e) {} + } + const arSub = subTabsRef && subTabsRef.current && activeTabRef && subTabsRef.current.find(s => s.id === activeTabRef.current && s.type === 'PIANO_ROLL' && s.isArmed); if (arSub) { window.SonicSF.playNote(pitch, velocity, 60000, undefined, arSub.instrumentProgram, null, ch, arSub.synth_engine); } else { diff --git a/app/static/js/services/soundfontPlayer.js b/app/static/js/services/soundfontPlayer.js index c1a7759..914ea19 100644 --- a/app/static/js/services/soundfontPlayer.js +++ b/app/static/js/services/soundfontPlayer.js @@ -36,6 +36,7 @@ let _initPromise = null; let _currentSfId = null; const _scheduledNotes = []; + const _sustainStates = new Array(16).fill(false); const SonicSF = { loadedFonts: {}, @@ -122,6 +123,9 @@ _channels[channel].bank = value; _channels[channel].isPercussion = (value === 128); } + if (controller === 64) { + _sustainStates[channel] = value >= 64; + } }, programChange: function (channel, program) { @@ -154,6 +158,11 @@ return { ..._channels[channel] }; }, + sustainActive: function (channel) { + if (channel < 0 || channel > 15) return false; + return _sustainStates[channel]; + }, + pitchBend: function (channel, value) { if (channel < 0 || channel > 15) return; if (_initialized && _synthInstance) {