From bbe605c0faf134040859a27bb6f6c6de40d7063a Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 9 Sep 2019 04:10:59 +0200 Subject: [PATCH] Send NoteOff on when muting MIDI, drop note events when silent --- libs/ardour/amp.cc | 84 ++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index 26c7e95c21..75a18cbf98 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -192,36 +192,9 @@ Amp::apply_gain (BufferSet& bufs, samplecnt_t sample_rate, samplecnt_t nframes, return target; } - /* MIDI Gain */ - if (midi_amp) { - /* don't Trim midi velocity -- only relevant for Midi on Audio tracks */ - for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) { - - gain_t delta; - if (target < initial) { - /* fade out: remove more and more of delta from initial */ - delta = -(initial - target); - } else { - /* fade in: add more and more of delta from initial */ - delta = target - initial; - } - - MidiBuffer& mb (*i); - - for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) { - Evoral::Event ev = *m; - - if (ev.is_note_on()) { - const gain_t scale = delta * (ev.time()/(double) nframes); - scale_midi_velocity (ev, fabsf (initial + scale)); - } - } - } - } - - /* Audio Gain */ - - /* Low pass filter coefficient: 1.0 - e^(-2.0 * π * f / 48000) f in Hz. + /* Apply Audio Gain first, calculate target LFP'ed gain coefficient + * + * Low pass filter coefficient: 1.0 - e^(-2.0 * π * f / 48000) f in Hz. * for f << SR, approx a ~= 6.2 * f / SR; */ const gain_t a = 156.825f / (gain_t)sample_rate; // 25 Hz LPF @@ -238,7 +211,46 @@ Amp::apply_gain (BufferSet& bufs, samplecnt_t sample_rate, samplecnt_t nframes, rv = lpf; } } - if (fabsf (rv - target) < GAIN_COEFF_DELTA) return target; + + if (fabsf (rv - target) < GAIN_COEFF_DELTA) { + rv = target; + } + + /* MIDI Velocity scale from initial to LPF target */ + if (midi_amp) { + /* don't Trim midi velocity -- only relevant for Midi on Audio tracks */ + for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) { + + gain_t delta; + if (rv < initial) { + /* fade out: remove more and more of delta from initial */ + delta = -(initial - rv); + } else { + /* fade in: add more and more of delta from initial */ + delta = rv - initial; + } + + MidiBuffer& mb (*i); + + for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) { + Evoral::Event ev = *m; + + if (ev.is_note_on()) { + const gain_t scale = delta * (ev.time() / (double) nframes); + scale_midi_velocity (ev, fabsf (initial + scale)); + } + } + + /* queue MIDI all-note-off when going silent */ + if (initial > GAIN_COEFF_SMALL && rv <= GAIN_COEFF_SMALL) { + for (uint8_t channel = 0; channel <= 0xF; channel++) { + uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_ALL_NOTES_OFF), 0 }; + mb.push_back (nframes - 1, 3, ev); + } + } + } + } + return rv; } @@ -278,14 +290,15 @@ Amp::apply_simple_gain (BufferSet& bufs, samplecnt_t nframes, gain_t target, boo if (fabsf (target) < GAIN_COEFF_SMALL) { if (midi_amp) { - /* don't Trim midi velocity -- only relevant for Midi on Audio tracks */ for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) { MidiBuffer& mb (*i); - for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) { + for (MidiBuffer::iterator m = mb.begin(); m != mb.end();) { Evoral::Event ev = *m; - if (ev.is_note_on()) { - ev.set_velocity (0); + if (ev.is_note_on() || ev.is_note_off()) { + m = mb.erase (m); + } else { + ++m; } } } @@ -298,7 +311,6 @@ Amp::apply_simple_gain (BufferSet& bufs, samplecnt_t nframes, gain_t target, boo } else if (target != GAIN_COEFF_UNITY) { if (midi_amp) { - /* don't Trim midi velocity -- only relevant for Midi on Audio tracks */ for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) { MidiBuffer& mb (*i);