+
+boost::shared_ptr<MidiBuffer>
+MidiTrack::get_gui_feed_buffer () const
+{
+ return midi_diskstream()->get_gui_feed_buffer ();
+}
+
+void
+MidiTrack::act_on_mute ()
+{
+ /* this is called right after our mute status has changed.
+ if we are now muted, send suitable output to shutdown
+ all our notes.
+
+ XXX we should should also stop all relevant note trackers.
+ */
+
+ /* If we haven't got a diskstream yet, there's nothing to worry about,
+ and we can't call get_channel_mask() anyway.
+ */
+ if (!midi_diskstream()) {
+ return;
+ }
+
+ if (muted() || _mute_master->muted_by_others_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<<channel) & mask) {
+
+ 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);
+
+ /* 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);
+ }
+}
+
+void
+MidiTrack::set_monitoring (MonitorChoice mc)
+{
+ if (mc != _monitoring) {
+
+ Track::set_monitoring (mc);
+
+ /* monitoring state changed, so flush out any on notes at the
+ * port level.
+ */
+
+ PortSet& ports (_output->ports());
+
+ for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
+ boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
+ if (mp) {
+ mp->require_resolve ();
+ }
+ }
+
+ boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
+
+ if (md) {
+ md->reset_tracker ();
+ }
+ }
+}
+
+MonitorState
+MidiTrack::monitoring_state () const
+{
+ MonitorState ms = Track::monitoring_state();
+ if (ms == MonitoringSilence) {
+ return MonitoringInput;
+ }
+ return ms;
+}
+