From bbe605c0faf134040859a27bb6f6c6de40d7063a Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 9 Sep 2019 04:10:59 +0200 Subject: Send NoteOff on when muting MIDI, drop note events when silent --- libs/ardour/amp.cc | 72 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 30 deletions(-) (limited to 'libs/ardour/amp.cc') 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,18 +192,42 @@ Amp::apply_gain (BufferSet& bufs, samplecnt_t sample_rate, samplecnt_t nframes, return target; } - /* MIDI Gain */ + /* 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 + + for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { + Sample* const buffer = i->data(); + double lpf = initial; + + for (pframes_t nx = 0; nx < nframes; ++nx) { + buffer[nx] *= lpf; + lpf += a * (target - lpf); + } + if (i == bufs.audio_begin()) { + rv = lpf; + } + } + + 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 (target < initial) { + if (rv < initial) { /* fade out: remove more and more of delta from initial */ - delta = -(initial - target); + delta = -(initial - rv); } else { /* fade in: add more and more of delta from initial */ - delta = target - initial; + delta = rv - initial; } MidiBuffer& mb (*i); @@ -212,33 +236,21 @@ Amp::apply_gain (BufferSet& bufs, samplecnt_t sample_rate, samplecnt_t nframes, Evoral::Event ev = *m; if (ev.is_note_on()) { - const gain_t scale = delta * (ev.time()/(double) nframes); + 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. - * for f << SR, approx a ~= 6.2 * f / SR; - */ - const gain_t a = 156.825f / (gain_t)sample_rate; // 25 Hz LPF - - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const buffer = i->data(); - double lpf = initial; - - for (pframes_t nx = 0; nx < nframes; ++nx) { - buffer[nx] *= lpf; - lpf += a * (target - lpf); - } - if (i == bufs.audio_begin()) { - rv = lpf; + /* 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); + } + } } } - if (fabsf (rv - target) < GAIN_COEFF_DELTA) return target; + 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); -- cgit v1.2.3