+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 (muted()) {
+ /* only send messages for channels we are using */
+
+ uint16_t mask = 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);
+ ev[1] = MIDI_CTL_ALL_NOTES_OFF;
+ write_immediate_event (3, ev);
+ }
+ }
+ }
+}
+
+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
+{
+ /* Explicit requests */
+
+ if (_monitoring & MonitorInput) {
+ return MonitoringInput;
+ }
+
+ if (_monitoring & MonitorDisk) {
+ return MonitoringDisk;
+ }
+
+ if (_session.transport_rolling()) {
+ return MonitoringDisk;
+ }
+
+ /* the return value here doesn't mean that we're actually monitoring
+ * input, let alone input *audio*. but it means that we are NOT
+ * monitoring silence. this allows us to still hear any audio generated
+ * by using internal generation techniques
+ */
+
+ return MonitoringInput;
+}