diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index 1b6314fa6f..a684c112c9 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -30,6 +30,7 @@ #include "ardour/types.h" #include "ardour/chan_count.h" #include "ardour/io_processor.h" +#include "ardour/midi_buffer.h" #include "ardour/gain_control.h" namespace ARDOUR { @@ -89,6 +90,8 @@ public: void run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool); + void set_midi_mute_mask (int); + /* supplemental method used with MIDI */ void flush_buffers (samplecnt_t nframes); @@ -157,6 +160,7 @@ protected: std::shared_ptr _amp; gain_t target_gain (); + void maybe_merge_midi_mute (BufferSet&); private: bool _no_outs_cuz_we_no_monitor; @@ -176,6 +180,8 @@ private: void output_changed (IOChange, void*); bool _no_panner_reset; + std::atomic _midi_mute_mask; + MidiBuffer _midi_mute_buffer; }; diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 4c84e960c8..76f5de50d0 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -65,6 +65,8 @@ Delivery::Delivery (Session& s, std::shared_ptr io, std::shared_ptr io, std::shared_ptrchanged.connect_same_thread (*this, std::bind (&Delivery::output_changed, this, _1, _2)); } @@ -90,6 +97,8 @@ Delivery::Delivery (Session& s, std::shared_ptr pannable, std::shared_ , _mute_master (mm) , _rta_active (false) , _no_panner_reset (false) + , _midi_mute_mask (0) + , _midi_mute_buffer (0) { if (pannable) { bool is_send = false; @@ -98,6 +107,10 @@ Delivery::Delivery (Session& s, std::shared_ptr pannable, std::shared_ } _display_to_user = false; + const size_t stamp_size = sizeof(samplepos_t); + const size_t etype_size = sizeof(Evoral::EventType); + const size_t mmb_size = 16 * (stamp_size + etype_size + 3); + _midi_mute_buffer.resize (mmb_size); if (_output) { _output->changed.connect_same_thread (*this, std::bind (&Delivery::output_changed, this, _1, _2)); @@ -267,6 +280,38 @@ Delivery::configure_io (ChanCount in, ChanCount out) return true; } +void +Delivery::maybe_merge_midi_mute (BufferSet& bufs) +{ + if (bufs.available().n_midi()) { + + int mask = _midi_mute_mask.load(); /* atomic */ + MidiBuffer& pmbuf (bufs.get_midi (0)); + + if (mask && (_current_gain < GAIN_COEFF_SMALL)) { + + /* mask set, and we have just been muted */ + + _midi_mute_buffer.clear (); + + for (uint8_t channel = 0; channel <= 0xF; channel++) { + + if ((1< ev (Evoral::MIDI_EVENT, 0, 3, buf); + _midi_mute_buffer.push_back (ev); + + /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may + silence notes that came from another non-muted track. */ + } + } + pmbuf.merge_from (_midi_mute_buffer, 0, 0, 0); /* last 3 args do not matter for MIDI */ + _midi_mute_mask = 0; + } + } +} + void Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool result_required) { @@ -343,6 +388,8 @@ Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample _amp->run (bufs, start_sample, end_sample, speed, nframes, true); } + maybe_merge_midi_mute (bufs); + RTABufferListPtr rtabuffers = _rtabuffers; if (_rta_active.load () && rtabuffers && !rtabuffers->empty ()) { uint32_t n_audio = bufs.count().n_audio(); @@ -721,3 +768,8 @@ Delivery::panner () const } } +void +Delivery::set_midi_mute_mask (int mask) +{ + _midi_mute_mask = mask; /* atomic */ +} diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index a8f0880049..2d5cc42d4b 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -333,6 +333,8 @@ InternalSend::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa Amp::apply_simple_gain (mixbufs, nframes, tgain); } + maybe_merge_midi_mute (mixbufs); + /* apply fader gain automation */ _amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ()); _amp->setup_gain_automation (start_sample + latency, end_sample + latency, nframes); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index eb12205048..4a793c33d0 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -915,24 +915,18 @@ MidiTrack::act_on_mute () if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) { /* only send messages for channels we are using */ - - uint16_t mask = _playback_filter.get_channel_mask(); - - for (uint8_t channel = 0; channel <= 0xF; channel++) { - - if ((1< p) { + std::shared_ptr delivery = std::dynamic_pointer_cast (p.lock()); + if (delivery) { + delivery->set_midi_mute_mask (_playback_filter.get_channel_mask()); } - } + }); /* Resolve active notes. */ - _disk_reader->resolve_tracker (_immediate_events, 0); + + if (!the_instrument()) { + _disk_reader->resolve_tracker (_immediate_events, 0); + } } }