+void
+MidiTrack::set_playback_channel_mask (uint16_t mask)
+{
+ if (_playback_filter.set_channel_mask(mask)) {
+ _session.set_dirty();
+ }
+}
+
+void
+MidiTrack::set_capture_channel_mask (uint16_t mask)
+{
+ if (_capture_filter.set_channel_mask(mask)) {
+ _session.set_dirty();
+ }
+}
+
+boost::shared_ptr<MidiPlaylist>
+MidiTrack::midi_playlist ()
+{
+ return midi_diskstream()->midi_playlist ();
+}
+
+void
+MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
+{
+ DataRecorded (src); /* EMIT SIGNAL */
+}
+
+bool
+MidiTrack::input_active () const
+{
+ return _input_active;
+}
+
+void
+MidiTrack::set_input_active (bool yn)
+{
+ if (yn != _input_active) {
+ _input_active = yn;
+ map_input_active (yn);
+ InputActiveChanged (); /* EMIT SIGNAL */
+ }
+}
+
+void
+MidiTrack::map_input_active (bool yn)
+{
+ if (!_input) {
+ return;
+ }
+
+ PortSet& ports (_input->ports());
+
+ for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
+ boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
+ if (yn != mp->input_active()) {
+ mp->set_input_active (yn);
+ }
+ }
+}
+
+void
+MidiTrack::track_input_active (IOChange change, void* /* src */)
+{
+ if (change.type & IOChange::ConfigurationChanged) {
+ map_input_active (_input_active);
+ }
+}
+
+boost::shared_ptr<Diskstream>
+MidiTrack::diskstream_factory (XMLNode const & node)
+{
+ return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
+}
+
+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)