2 Copyright (C) 2006 Paul Davis
3 Author: David Robillard
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "pbd/enumwriter.h"
22 #include "pbd/convert.h"
23 #include "evoral/midi_util.h"
25 #include "ardour/buffer_set.h"
26 #include "ardour/debug.h"
27 #include "ardour/delivery.h"
28 #include "ardour/meter.h"
29 #include "ardour/midi_diskstream.h"
30 #include "ardour/midi_playlist.h"
31 #include "ardour/midi_port.h"
32 #include "ardour/midi_track.h"
33 #include "ardour/parameter_types.h"
34 #include "ardour/port.h"
35 #include "ardour/processor.h"
36 #include "ardour/session.h"
37 #include "ardour/session_playlists.h"
38 #include "ardour/utils.h"
43 class InterThreadInfo;
50 using namespace ARDOUR;
53 MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
54 : Track (sess, name, flag, mode, DataType::MIDI)
55 , _immediate_events(1024) // FIXME: size?
56 , _step_edit_ring_buffer(64) // FIXME: size?
57 , _note_mode(Sustained)
58 , _step_editing (false)
59 , _input_active (true)
60 , _playback_channel_mask(0x0000ffff)
61 , _capture_channel_mask(0x0000ffff)
65 MidiTrack::~MidiTrack ()
76 _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
81 boost::shared_ptr<Diskstream>
82 MidiTrack::create_diskstream ()
84 MidiDiskstream::Flag dflags = MidiDiskstream::Flag (MidiDiskstream::Recordable);
86 assert(_mode != Destructive);
88 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
93 MidiTrack::set_record_enabled (bool yn, void *src)
99 Track::set_record_enabled (yn, src);
103 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
105 /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
106 and the diskstream must be set up to fill its buffers using the correct _note_mode.
108 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
109 mds->set_note_mode (_note_mode);
111 Track::set_diskstream (ds);
113 mds->reset_tracker ();
115 _diskstream->set_track (this);
116 _diskstream->set_destructive (_mode == Destructive);
117 _diskstream->set_record_enabled (false);
119 _diskstream_data_recorded_connection.disconnect ();
120 mds->DataRecorded.connect_same_thread (
121 _diskstream_data_recorded_connection,
122 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
124 DiskstreamChanged (); /* EMIT SIGNAL */
127 boost::shared_ptr<MidiDiskstream>
128 MidiTrack::midi_diskstream() const
130 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
134 MidiTrack::set_state (const XMLNode& node, int version)
136 const XMLProperty *prop;
138 /* This must happen before Track::set_state(), as there will be a buffer
139 fill during that call, and we must fill buffers using the correct
142 if ((prop = node.property (X_("note-mode"))) != 0) {
143 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
145 _note_mode = Sustained;
148 if (Track::set_state (node, version)) {
152 // No destructive MIDI tracks (yet?)
155 if ((prop = node.property ("input-active")) != 0) {
156 set_input_active (string_is_affirmative (prop->value()));
159 ChannelMode playback_channel_mode = AllChannels;
160 ChannelMode capture_channel_mode = AllChannels;
162 if ((prop = node.property ("playback-channel-mode")) != 0) {
163 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
165 if ((prop = node.property ("capture-channel-mode")) != 0) {
166 capture_channel_mode = ChannelMode (string_2_enum(prop->value(), capture_channel_mode));
168 if ((prop = node.property ("channel-mode")) != 0) {
169 /* 3.0 behaviour where capture and playback modes were not separated */
170 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
171 capture_channel_mode = playback_channel_mode;
174 unsigned int playback_channel_mask = 0xffff;
175 unsigned int capture_channel_mask = 0xffff;
177 if ((prop = node.property ("playback-channel-mask")) != 0) {
178 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
180 if ((prop = node.property ("capture-channel-mask")) != 0) {
181 sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
183 if ((prop = node.property ("channel-mask")) != 0) {
184 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
185 capture_channel_mask = playback_channel_mask;
188 set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
189 set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
191 pending_state = const_cast<XMLNode*> (&node);
193 if (_session.state_of_the_state() & Session::Loading) {
194 _session.StateReady.connect_same_thread (
195 *this, boost::bind (&MidiTrack::set_state_part_two, this));
197 set_state_part_two ();
204 MidiTrack::state(bool full_state)
206 XMLNode& root (Track::state(full_state));
207 XMLNode* freeze_node;
210 if (_freeze_record.playlist) {
213 freeze_node = new XMLNode (X_("freeze-info"));
214 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
215 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
217 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
218 inode = new XMLNode (X_("processor"));
219 (*i)->id.print (buf, sizeof(buf));
220 inode->add_property (X_("id"), buf);
221 inode->add_child_copy ((*i)->state);
223 freeze_node->add_child_nocopy (*inode);
226 root.add_child_nocopy (*freeze_node);
229 root.add_property("playback_channel-mode", enum_2_string(get_playback_channel_mode()));
230 root.add_property("capture_channel-mode", enum_2_string(get_capture_channel_mode()));
231 snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
232 root.add_property("playback-channel-mask", buf);
233 snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
234 root.add_property("capture-channel-mask", buf);
236 root.add_property ("note-mode", enum_2_string (_note_mode));
237 root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
238 root.add_property ("input-active", (_input_active ? "yes" : "no"));
244 MidiTrack::set_state_part_two ()
248 LocaleGuard lg (X_("POSIX"));
250 /* This is called after all session state has been restored but before
251 have been made ports and connections are established.
254 if (pending_state == 0) {
258 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
260 _freeze_record.state = Frozen;
262 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
265 _freeze_record.processor_info.clear ();
267 if ((prop = fnode->property (X_("playlist"))) != 0) {
268 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
270 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
272 _freeze_record.playlist.reset();
273 _freeze_record.state = NoFreeze;
278 if ((prop = fnode->property (X_("state"))) != 0) {
279 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
282 XMLNodeConstIterator citer;
283 XMLNodeList clist = fnode->children();
285 for (citer = clist.begin(); citer != clist.end(); ++citer) {
286 if ((*citer)->name() != X_("processor")) {
290 if ((prop = (*citer)->property (X_("id"))) == 0) {
294 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
295 boost::shared_ptr<Processor>());
296 frii->id = prop->value ();
297 _freeze_record.processor_info.push_back (frii);
301 if (midi_diskstream ()) {
302 midi_diskstream()->set_block_size (_session.get_block_size ());
308 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
312 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
314 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
316 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
317 framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
318 if (can_internal_playback_seek(llabs(playback_distance))) {
319 /* TODO should declick, and/or note-off */
320 internal_playback_seek(playback_distance);
325 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
327 if (n_outputs().n_total() == 0 && _processors.empty()) {
333 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
339 framepos_t transport_frame = _session.transport_frame();
342 framecnt_t playback_distance;
344 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
345 /* need to do this so that the diskstream sets its
346 playback distance to zero, thus causing diskstream::commit
349 BufferSet bufs; /* empty set - is OK, since nothing will happen */
351 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
352 need_butler = diskstream->commit (playback_distance);
356 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
358 fill_buffers_with_input (bufs, _input, nframes);
360 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
361 _meter->run (bufs, start_frame, end_frame, nframes, true);
364 /* filter captured data before the diskstream sees it */
366 filter_channels (bufs, get_capture_channel_mode(), get_capture_channel_mask());
370 if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
371 need_butler = diskstream->commit (playback_distance);
376 /* filter playback data before we do anything else */
378 filter_channels (bufs, get_playback_channel_mode(), get_playback_channel_mask ());
380 if (monitoring_state() == MonitoringInput) {
382 /* not actually recording, but we want to hear the input material anyway,
383 at least potentially (depending on monitoring options)
386 /* because the playback buffer is event based and not a
387 * continuous stream, we need to make sure that we empty
388 * it of events every cycle to avoid it filling up with events
389 * read from disk, while we are actually monitoring input
392 diskstream->flush_playback (start_frame, end_frame);
397 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
399 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
401 /* final argument: don't waste time with automation if we're not recording or rolling */
403 process_output_buffers (bufs, start_frame, end_frame, nframes,
404 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
406 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
407 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
409 d->flush_buffers (nframes);
413 need_butler = diskstream->commit (playback_distance);
419 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
421 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
423 if (ret == 0 && _step_editing) {
424 push_midi_input_to_step_edit_ringbuffer (nframes);
431 MidiTrack::realtime_locate ()
433 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
439 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
440 (*i)->realtime_locate ();
443 midi_diskstream()->reset_tracker ();
447 MidiTrack::realtime_handle_transport_stopped ()
449 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
455 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
456 (*i)->realtime_handle_transport_stopped ();
461 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
463 PortSet& ports (_input->ports());
465 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
467 Buffer& b (p->get_buffer (nframes));
468 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
471 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
473 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
475 /* note on, since for step edit, note length is determined
479 if (ev.is_note_on()) {
480 /* we don't care about the time for this purpose */
481 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
488 MidiTrack::filter_channels (BufferSet& bufs, ChannelMode mode, uint32_t mask)
490 if (mode == AllChannels) {
494 MidiBuffer& buf (bufs.get_midi (0));
496 for (MidiBuffer::iterator e = buf.begin(); e != buf.end(); ) {
498 Evoral::MIDIEvent<framepos_t> ev(*e, false);
500 if (ev.is_channel_event()) {
503 if (0 == ((1<<ev.channel()) & mask)) {
510 ev.set_channel (PBD::ffs (mask) - 1);
514 /* handled by the opening if() */
525 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
527 MidiBuffer& buf (bufs.get_midi (0));
529 // Append immediate events
531 if (_immediate_events.read_space()) {
533 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
534 name(), _immediate_events.read_space()));
536 /* write as many of the immediate events as we can, but give "true" as
537 * the last argument ("stop on overflow in destination") so that we'll
538 * ship the rest out next time.
540 * the Port::port_offset() + (nframes-1) argument puts all these events at the last
541 * possible position of the output buffer, so that we do not
542 * violate monotonicity when writing. Port::port_offset() will
543 * be non-zero if we're in a split process cycle.
545 _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
550 MidiTrack::export_stuff (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framecnt_t /*nframes*/,
551 boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/, bool /*for_export*/, bool /*for_freeze*/)
556 boost::shared_ptr<Region>
557 MidiTrack::bounce (InterThreadInfo& /*itt*/)
559 std::cerr << "MIDI bounce currently unsupported" << std::endl;
560 return boost::shared_ptr<Region> ();
564 boost::shared_ptr<Region>
565 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/,
566 boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/)
568 std::cerr << "MIDI bounce range currently unsupported" << std::endl;
569 return boost::shared_ptr<Region> ();
573 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
575 std::cerr << "MIDI freeze currently unsupported" << std::endl;
579 MidiTrack::unfreeze ()
581 _freeze_record.state = UnFrozen;
582 FreezeChange (); /* EMIT SIGNAL */
586 MidiTrack::set_note_mode (NoteMode m)
589 midi_diskstream()->set_note_mode(m);
593 MidiTrack::describe_parameter (Evoral::Parameter param)
595 const std::string str(instrument_info().get_controller_name(param));
596 return str.empty() ? Automatable::describe_parameter(param) : str;
600 MidiTrack::midi_panic()
602 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
603 for (uint8_t channel = 0; channel <= 0xF; channel++) {
604 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
605 write_immediate_event(3, ev);
606 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
607 write_immediate_event(3, ev);
608 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
609 write_immediate_event(3, ev);
613 /** \return true on success, false on failure (no buffer space left)
616 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
618 if (!Evoral::midi_event_is_valid(buf, size)) {
619 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
622 const uint32_t type = midi_parameter_type(buf[0]);
623 return (_immediate_events.write (0, type, size, buf) == size);
627 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
629 switch (param.type()) {
630 case MidiCCAutomation:
631 case MidiPgmChangeAutomation:
632 case MidiPitchBenderAutomation:
633 case MidiChannelPressureAutomation:
634 case MidiSystemExclusiveAutomation:
635 /* The track control for MIDI parameters is for immediate events to act
636 as a control surface, write/touch for them is not currently
640 Automatable::set_parameter_automation_state(param, state);
645 MidiTrack::MidiControl::set_value(double val)
647 const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
651 cerr << "MIDIControl value is infinity" << endl;
652 } else if (isnan(val)) {
653 cerr << "MIDIControl value is NaN" << endl;
654 } else if (val < parameter.min()) {
655 cerr << "MIDIControl value is < " << parameter.min() << endl;
656 } else if (val > parameter.max()) {
657 cerr << "MIDIControl value is > " << parameter.max() << endl;
666 assert(val <= parameter.max());
667 if ( ! _list || ! automation_playback()) {
669 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
670 switch(parameter.type()) {
671 case MidiCCAutomation:
672 ev[0] += MIDI_CMD_CONTROL;
673 ev[1] = parameter.id();
677 case MidiPgmChangeAutomation:
679 ev[0] += MIDI_CMD_PGM_CHANGE;
683 case MidiChannelPressureAutomation:
685 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
689 case MidiPitchBenderAutomation:
690 ev[0] += MIDI_CMD_BENDER;
691 ev[1] = 0x7F & int(val);
692 ev[2] = 0x7F & (int(val) >> 7);
698 _route->write_immediate_event(size, ev);
701 AutomationControl::set_value(val);
705 MidiTrack::set_step_editing (bool yn)
707 if (_session.record_status() != Session::Disabled) {
711 if (yn != _step_editing) {
713 StepEditStatusChange (yn);
717 boost::shared_ptr<SMFSource>
718 MidiTrack::write_source (uint32_t)
720 return midi_diskstream()->write_source ();
724 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
726 ChannelMode old = get_playback_channel_mode ();
727 uint16_t old_mask = get_playback_channel_mask ();
729 if (old != mode || mask != old_mask) {
730 _set_playback_channel_mode (mode, mask);
731 PlaybackChannelModeChanged ();
732 _session.set_dirty ();
737 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
739 ChannelMode old = get_capture_channel_mode ();
740 uint16_t old_mask = get_capture_channel_mask ();
742 if (old != mode || mask != old_mask) {
743 _set_capture_channel_mode (mode, mask);
744 CaptureChannelModeChanged ();
745 _session.set_dirty ();
750 MidiTrack::set_playback_channel_mask (uint16_t mask)
752 uint16_t old = get_playback_channel_mask();
755 _set_playback_channel_mask (mask);
756 PlaybackChannelMaskChanged ();
757 _session.set_dirty ();
762 MidiTrack::set_capture_channel_mask (uint16_t mask)
764 uint16_t old = get_capture_channel_mask();
767 _set_capture_channel_mask (mask);
768 CaptureChannelMaskChanged ();
769 _session.set_dirty ();
773 boost::shared_ptr<MidiPlaylist>
774 MidiTrack::midi_playlist ()
776 return midi_diskstream()->midi_playlist ();
780 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
782 DataRecorded (src); /* EMIT SIGNAL */
786 MidiTrack::input_active () const
788 return _input_active;
792 MidiTrack::set_input_active (bool yn)
794 if (yn != _input_active) {
796 map_input_active (yn);
797 InputActiveChanged (); /* EMIT SIGNAL */
802 MidiTrack::map_input_active (bool yn)
808 PortSet& ports (_input->ports());
810 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
811 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
812 if (yn != mp->input_active()) {
813 mp->set_input_active (yn);
819 MidiTrack::track_input_active (IOChange change, void* /* src */)
821 if (change.type & IOChange::ConfigurationChanged) {
822 map_input_active (_input_active);
826 boost::shared_ptr<Diskstream>
827 MidiTrack::diskstream_factory (XMLNode const & node)
829 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
832 boost::shared_ptr<MidiBuffer>
833 MidiTrack::get_gui_feed_buffer () const
835 return midi_diskstream()->get_gui_feed_buffer ();
839 MidiTrack::act_on_mute ()
841 /* this is called right after our mute status has changed.
842 if we are now muted, send suitable output to shutdown
845 XXX we should should also stop all relevant note trackers.
848 /* If we haven't got a diskstream yet, there's nothing to worry about,
849 and we can't call get_channel_mask() anyway.
851 if (!midi_diskstream()) {
856 /* only send messages for channels we are using */
858 uint16_t mask = get_playback_channel_mask();
860 for (uint8_t channel = 0; channel <= 0xF; channel++) {
862 if ((1<<channel) & mask) {
864 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
865 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
866 write_immediate_event (3, ev);
867 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
868 write_immediate_event (3, ev);
875 MidiTrack::set_monitoring (MonitorChoice mc)
877 if (mc != _monitoring) {
879 Track::set_monitoring (mc);
881 /* monitoring state changed, so flush out any on notes at the
885 PortSet& ports (_output->ports());
887 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
888 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
890 mp->require_resolve ();
894 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
897 md->reset_tracker ();
903 MidiTrack::monitoring_state () const
905 MonitorState ms = Track::monitoring_state();
906 if (ms == MonitoringSilence) {
907 return MonitoringInput;