Resolve only active notes when muted/non-soloed.
authorDavid Robillard <d@drobilla.net>
Tue, 24 Mar 2015 17:47:37 +0000 (13:47 -0400)
committerDavid Robillard <d@drobilla.net>
Tue, 24 Mar 2015 17:48:43 +0000 (13:48 -0400)
Fixes bug #6206.

libs/ardour/ardour/midi_diskstream.h
libs/ardour/ardour/midi_ring_buffer.h
libs/ardour/midi_diskstream.cc
libs/ardour/midi_ring_buffer.cc
libs/ardour/midi_track.cc
libs/ardour/mute_master.cc
libs/ardour/session.cc

index 742b327b363c5eb234575d882b3547f2ae6da183..58b74bd54f16718ee40402a056643bea3fd2fa4d 100644 (file)
@@ -72,6 +72,7 @@ class LIBARDOUR_API MidiDiskstream : public Diskstream
        void set_record_enabled (bool yn);
        
        void reset_tracker ();
        void set_record_enabled (bool yn);
        
        void reset_tracker ();
+       void resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time);
 
        boost::shared_ptr<MidiPlaylist> midi_playlist ();
 
 
        boost::shared_ptr<MidiPlaylist> midi_playlist ();
 
index d89d85b2d7c2bc85c4b3610639cb9a660f8ec537..652f1c49cfa22a89d6a53166cd64090071ad7df6 100644 (file)
@@ -56,6 +56,7 @@ public:
 
        void reset_tracker ();
        void resolve_tracker (MidiBuffer& dst, framepos_t);
 
        void reset_tracker ();
        void resolve_tracker (MidiBuffer& dst, framepos_t);
+       void resolve_tracker (Evoral::EventSink<framepos_t>& dst, framepos_t);
 
 private:
        MidiStateTracker _tracker;
 
 private:
        MidiStateTracker _tracker;
index 9795d57b5c65d96b7a1dc8cea0e5d11fa6c229f1..f6ba10342ac8c08d48154ba45ff39eec8d276d02 100644 (file)
@@ -1554,6 +1554,19 @@ MidiDiskstream::reset_tracker ()
        }
 }
 
        }
 }
 
+void
+MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
+{
+       _playback_buf->resolve_tracker(buffer, time);
+
+       boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
+
+       if (mp) {
+               mp->reset_note_trackers ();
+       }
+}
+
+
 boost::shared_ptr<MidiPlaylist>
 MidiDiskstream::midi_playlist ()
 {
 boost::shared_ptr<MidiPlaylist>
 MidiDiskstream::midi_playlist ()
 {
index 5bd3f947e27ad6ace2fe33769b93bb598791ea92..658583322ee909efbea4644374cfb5744f050dd0 100644 (file)
@@ -303,6 +303,13 @@ MidiRingBuffer<T>::resolve_tracker (MidiBuffer& dst, framepos_t t)
        _tracker.resolve_notes (dst, t);
 }
 
        _tracker.resolve_notes (dst, t);
 }
 
+template<typename T>
+void
+MidiRingBuffer<T>::resolve_tracker (Evoral::EventSink<framepos_t>& dst, framepos_t t)
+{
+       _tracker.resolve_notes(dst, t);
+}
+
 template class MidiRingBuffer<framepos_t>;
 
 }  // namespace ARDOUR
 template class MidiRingBuffer<framepos_t>;
 
 }  // namespace ARDOUR
index 6e59600990c37e06e86a37fe829deb24c9751409..770e4da3fe4946f61291bec53097faf19ca3a560 100644 (file)
@@ -892,7 +892,7 @@ MidiTrack::act_on_mute ()
                return;
        }
 
                return;
        }
 
-       if (muted()) {
+       if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) {
                /* only send messages for channels we are using */
 
                uint16_t mask = get_playback_channel_mask();
                /* only send messages for channels we are using */
 
                uint16_t mask = get_playback_channel_mask();
@@ -904,10 +904,14 @@ MidiTrack::act_on_mute ()
                                DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
                                uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
                                write_immediate_event (3, ev);
                                DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
                                uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
                                write_immediate_event (3, ev);
-                               ev[1] = MIDI_CTL_ALL_NOTES_OFF;
-                               write_immediate_event (3, ev);
+
+                               /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
+                                  silence notes that came from another non-muted track. */
                        }
                }
                        }
                }
+
+               /* Resolve active notes. */
+               midi_diskstream()->resolve_tracker(_immediate_events, 0);
        }
 }
        
        }
 }
        
index 9f2ed08dab5ce5f7fd4af3000d34dec150d7708b..5734af8a3d812d6ce9af20e50721e232c88017b1 100644 (file)
@@ -31,6 +31,9 @@
 using namespace ARDOUR;
 using namespace std;
 
 using namespace ARDOUR;
 using namespace std;
 
+const MuteMaster::MutePoint MuteMaster::AllPoints = MuteMaster::MutePoint(
+       PreFader|PostFader|Listen|Main);
+
 MuteMaster::MuteMaster (Session& s, const std::string&)
        : SessionHandleRef (s)
        , _mute_point (MutePoint (0))
 MuteMaster::MuteMaster (Session& s, const std::string&)
        : SessionHandleRef (s)
        , _mute_point (MutePoint (0))
index 9e3e168242e7f63bada5a0d2fc08926564065f2f..7afeebb416b0c0c649201e40f177640638553637 100644 (file)
@@ -3022,6 +3022,7 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p
 
        for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
                DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
 
        for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
                DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
+               (*i)->act_on_mute ();
                (*i)->mute_changed (this);
        }
 
                (*i)->mute_changed (this);
        }