fixes for 64 bit OS X build (c/o david robillard); tested on Lion & Tiger
[ardour.git] / libs / ardour / midi_track.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3     Author: David Robillard
4
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.
9
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.
14
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.
18 */
19
20 #include "pbd/error.h"
21
22 #include "pbd/enumwriter.h"
23 #include "pbd/convert.h"
24 #include "midi++/events.h"
25 #include "evoral/midi_util.h"
26
27 #include "ardour/amp.h"
28 #include "ardour/buffer_set.h"
29 #include "ardour/debug.h"
30 #include "ardour/delivery.h"
31 #include "ardour/io_processor.h"
32 #include "ardour/meter.h"
33 #include "ardour/midi_diskstream.h"
34 #include "ardour/midi_playlist.h"
35 #include "ardour/midi_port.h"
36 #include "ardour/midi_region.h"
37 #include "ardour/midi_source.h"
38 #include "ardour/midi_track.h"
39 #include "ardour/panner.h"
40 #include "ardour/port.h"
41 #include "ardour/processor.h"
42 #include "ardour/route_group_specialized.h"
43 #include "ardour/session.h"
44 #include "ardour/session_playlists.h"
45 #include "ardour/utils.h"
46
47 #include "i18n.h"
48
49 using namespace std;
50 using namespace ARDOUR;
51 using namespace PBD;
52
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         , _midi_thru (true)
60         , _input_active (true)
61 {
62 }
63
64 MidiTrack::~MidiTrack ()
65 {
66 }
67
68 int
69 MidiTrack::init ()
70 {
71         if (Track::init ()) {
72                 return -1;
73         }
74
75         _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
76
77         return 0;
78 }
79
80 boost::shared_ptr<Diskstream>
81 MidiTrack::create_diskstream ()
82 {
83         MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
84
85         if (_flags & Hidden) {
86                 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
87         } else {
88                 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
89         }
90
91         assert(_mode != Destructive);
92
93         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
94 }
95
96
97 void
98 MidiTrack::set_record_enabled (bool yn, void *src)
99 {
100         if (_step_editing) {
101                 return;
102         }
103
104         Track::set_record_enabled (yn, src);
105 }
106
107 void
108 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
109 {
110         Track::set_diskstream (ds);
111
112         midi_diskstream()->reset_tracker ();    
113
114         _diskstream->set_track (this);
115         _diskstream->set_destructive (_mode == Destructive);
116         _diskstream->set_record_enabled (false);
117
118         _diskstream_data_recorded_connection.disconnect ();
119         boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
120         mds->DataRecorded.connect_same_thread (
121                 _diskstream_data_recorded_connection,
122                 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
123
124         DiskstreamChanged (); /* EMIT SIGNAL */
125 }
126
127 boost::shared_ptr<MidiDiskstream>
128 MidiTrack::midi_diskstream() const
129 {
130         return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
131 }
132
133 int
134 MidiTrack::set_state (const XMLNode& node, int version)
135 {
136         const XMLProperty *prop;
137
138         if (Track::set_state (node, version)) {
139                 return -1;
140         }
141
142         // No destructive MIDI tracks (yet?)
143         _mode = Normal;
144
145         if ((prop = node.property (X_("note-mode"))) != 0) {
146                 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
147         } else {
148                 _note_mode = Sustained;
149         }
150
151         if ((prop = node.property ("midi-thru")) != 0) {
152                 set_midi_thru (string_is_affirmative (prop->value()));
153         }
154
155         if ((prop = node.property ("input-active")) != 0) {
156                 set_input_active (string_is_affirmative (prop->value()));
157         }
158
159         pending_state = const_cast<XMLNode*> (&node);
160
161         if (_session.state_of_the_state() & Session::Loading) {
162                 _session.StateReady.connect_same_thread (
163                         *this, boost::bind (&MidiTrack::set_state_part_two, this));
164         } else {
165                 set_state_part_two ();
166         }
167
168         return 0;
169 }
170
171 XMLNode&
172 MidiTrack::state(bool full_state)
173 {
174         XMLNode& root (Track::state(full_state));
175         XMLNode* freeze_node;
176         char buf[64];
177
178         if (_freeze_record.playlist) {
179                 XMLNode* inode;
180
181                 freeze_node = new XMLNode (X_("freeze-info"));
182                 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
183                 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
184
185                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
186                         inode = new XMLNode (X_("processor"));
187                         (*i)->id.print (buf, sizeof(buf));
188                         inode->add_property (X_("id"), buf);
189                         inode->add_child_copy ((*i)->state);
190
191                         freeze_node->add_child_nocopy (*inode);
192                 }
193
194                 root.add_child_nocopy (*freeze_node);
195         }
196
197         root.add_property (X_("note-mode"), enum_2_string (_note_mode));
198
199         root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
200         root.add_property ("note-mode", enum_2_string (_note_mode));
201         root.add_property ("midi-thru", (_midi_thru ? "yes" : "no"));
202         root.add_property ("input-active", (_input_active ? "yes" : "no"));
203
204         return root;
205 }
206
207 void
208 MidiTrack::set_state_part_two ()
209 {
210         XMLNode* fnode;
211         XMLProperty* prop;
212         LocaleGuard lg (X_("POSIX"));
213
214         /* This is called after all session state has been restored but before
215            have been made ports and connections are established.
216         */
217
218         if (pending_state == 0) {
219                 return;
220         }
221
222         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
223
224                 _freeze_record.state = Frozen;
225
226                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
227                         delete *i;
228                 }
229                 _freeze_record.processor_info.clear ();
230
231                 if ((prop = fnode->property (X_("playlist"))) != 0) {
232                         boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
233                         if (pl) {
234                                 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
235                         } else {
236                                 _freeze_record.playlist.reset();
237                                 _freeze_record.state = NoFreeze;
238                         return;
239                         }
240                 }
241
242                 if ((prop = fnode->property (X_("state"))) != 0) {
243                         _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
244                 }
245
246                 XMLNodeConstIterator citer;
247                 XMLNodeList clist = fnode->children();
248
249                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
250                         if ((*citer)->name() != X_("processor")) {
251                                 continue;
252                         }
253
254                         if ((prop = (*citer)->property (X_("id"))) == 0) {
255                                 continue;
256                         }
257
258                         FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
259                                                                                    boost::shared_ptr<Processor>());
260                         frii->id = prop->value ();
261                         _freeze_record.processor_info.push_back (frii);
262                 }
263         }
264
265         if (midi_diskstream ()) {
266                 midi_diskstream()->set_block_size (_session.get_block_size ());
267         }
268
269         return;
270 }
271
272 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
273  *  or set to false.
274  */
275 int
276 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
277 {
278         Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
279         if (!lm.locked()) {
280                 return 0;
281         }
282
283         boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
284
285         automation_snapshot (start_frame);
286
287         if (n_outputs().n_total() == 0 && _processors.empty()) {
288                 return 0;
289         }
290
291         if (!_active) {
292                 silence (nframes);
293                 return 0;
294         }
295
296         framepos_t transport_frame = _session.transport_frame();
297
298         int dret;
299         framecnt_t playback_distance;
300
301         if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
302                 /* need to do this so that the diskstream sets its
303                    playback distance to zero, thus causing diskstream::commit
304                    to do nothing.
305                    */
306                 dret = diskstream->process (transport_frame, 0, playback_distance);
307                 need_butler = diskstream->commit (playback_distance);
308                 return dret;
309         }
310
311         _silent = false;
312
313         if ((dret = diskstream->process (transport_frame, nframes, playback_distance)) != 0) {
314                 need_butler = diskstream->commit (playback_distance);
315                 silence (nframes);
316                 return dret;
317         }
318
319         /* special condition applies */
320
321         if (_meter_point == MeterInput) {
322                 _input->process_input (_meter, start_frame, end_frame, nframes);
323         }
324
325         if (monitoring_state() == MonitoringInput) {
326
327                 /* not actually recording, but we want to hear the input material anyway,
328                    at least potentially (depending on monitoring options)
329                 */
330
331                 passthru (start_frame, end_frame, nframes, 0);
332
333         } else {
334                 /*
335                    XXX is it true that the earlier test on n_outputs()
336                    means that we can avoid checking it again here? i think
337                    so, because changing the i/o configuration of an IO
338                    requires holding the AudioEngine lock, which we hold
339                    while in the process() tree.
340                    */
341
342
343                 /* copy the diskstream data to all output buffers */
344
345                 //const size_t limit = n_process_buffers().n_audio();
346                 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
347                 MidiBuffer& mbuf (bufs.get_midi (0));
348
349                 /* we are a MIDI track, so we always start the chain with a single-channel diskstream */
350                 ChanCount c;
351                 c.set_audio (0);
352                 c.set_midi (1);
353                 bufs.set_count (c);
354
355                 diskstream->get_playback (mbuf, nframes);
356
357                 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
358
359                 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
360
361                 /* final argument: don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
362
363                 process_output_buffers (
364                         bufs, start_frame, end_frame, nframes,
365                         declick, (!diskstream->record_enabled() && !_session.transport_stopped())
366                         );
367         }
368
369         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
370                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
371                 if (d) {
372                         d->flush_buffers (nframes, end_frame - start_frame - 1);
373                 }
374         }
375
376         need_butler = diskstream->commit (playback_distance);
377         
378         return 0;
379 }
380
381 int
382 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
383 {
384         int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
385
386         if (ret == 0 && _step_editing) {
387                 push_midi_input_to_step_edit_ringbuffer (nframes);
388         }
389
390         return ret;
391 }
392
393 void
394 MidiTrack::realtime_locate ()
395 {
396         Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
397
398         if (!lm.locked ()) {
399                 return;
400         }
401
402         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
403                 (*i)->realtime_locate ();
404         }
405
406         midi_diskstream()->reset_tracker ();
407 }
408
409 void
410 MidiTrack::realtime_handle_transport_stopped ()
411 {
412         Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
413
414         if (!lm.locked ()) {
415                 return;
416         }
417
418         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
419                 (*i)->realtime_handle_transport_stopped ();
420         }
421 }
422
423 void
424 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
425 {
426         PortSet& ports (_input->ports());
427
428         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
429
430                 Buffer& b (p->get_buffer (nframes));
431                 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
432                 assert (mb);
433
434                 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
435
436                         const Evoral::MIDIEvent<framepos_t> ev(*e, false);
437
438                         /* note on, since for step edit, note length is determined
439                            elsewhere
440                         */
441
442                         if (ev.is_note_on()) {
443                                 /* we don't care about the time for this purpose */
444                                 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
445                         }
446                 }
447         }
448 }
449
450 void
451 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
452 {
453         MidiBuffer& buf (bufs.get_midi (0));
454
455         // Append immediate events
456
457         if (_immediate_events.read_space()) {
458
459                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
460                                                             name(), _immediate_events.read_space()));
461
462                 /* write as many of the immediate events as we can, but give "true" as
463                  * the last argument ("stop on overflow in destination") so that we'll
464                  * ship the rest out next time.
465                  *
466                  * the (nframes-1) argument puts all these events at the last
467                  * possible position of the output buffer, so that we do not
468                  * violate monotonicity when writing.
469                  */
470
471                 _immediate_events.read (buf, 0, 1, nframes-1, true);
472         }
473
474         // MIDI thru: send incoming data "through" output
475         if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) {
476                 buf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes));
477         }
478 }
479
480 int
481 MidiTrack::export_stuff (BufferSet& /*bufs*/, framecnt_t /*nframes*/, framepos_t /*end_frame*/)
482 {
483         return -1;
484 }
485
486 boost::shared_ptr<Region>
487 MidiTrack::bounce (InterThreadInfo& /*itt*/)
488 {
489         std::cerr << "MIDI bounce currently unsupported" << std::endl;
490         return boost::shared_ptr<Region> ();
491 }
492
493
494 boost::shared_ptr<Region>
495 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/, bool /*enable_processing*/)
496 {
497         std::cerr << "MIDI bounce range currently unsupported" << std::endl;
498         return boost::shared_ptr<Region> ();
499 }
500
501 void
502 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
503 {
504         std::cerr << "MIDI freeze currently unsupported" << std::endl;
505 }
506
507 void
508 MidiTrack::unfreeze ()
509 {
510         _freeze_record.state = UnFrozen;
511         FreezeChange (); /* EMIT SIGNAL */
512 }
513
514 void
515 MidiTrack::set_note_mode (NoteMode m)
516 {
517         _note_mode = m;
518         midi_diskstream()->set_note_mode(m);
519 }
520
521 void
522 MidiTrack::midi_panic()
523 {
524         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
525         for (uint8_t channel = 0; channel <= 0xF; channel++) {
526                 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
527                 write_immediate_event(3, ev);
528                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
529                 write_immediate_event(3, ev);
530                 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
531                 write_immediate_event(3, ev);
532         }
533 }
534
535 /** \return true on success, false on failure (no buffer space left)
536  */
537 bool
538 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
539 {
540         if (!Evoral::midi_event_is_valid(buf, size)) {
541                 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
542                 return false;
543         }
544         const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
545         return (_immediate_events.write(0, type, size, buf) == size);
546 }
547
548 void
549 MidiTrack::MidiControl::set_value(double val)
550 {
551         bool valid = false;
552         if (isinf(val)) {
553                 cerr << "MIDIControl value is infinity" << endl;
554         } else if (isnan(val)) {
555                 cerr << "MIDIControl value is NaN" << endl;
556         } else if (val < _list->parameter().min()) {
557                 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
558         } else if (val > _list->parameter().max()) {
559                 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
560         } else {
561                 valid = true;
562         }
563
564         if (!valid) {
565                 return;
566         }
567
568         assert(val <= _list->parameter().max());
569         if ( ! automation_playback()) {
570                 size_t size = 3;
571                 uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
572                 switch(_list->parameter().type()) {
573                 case MidiCCAutomation:
574                         ev[0] += MIDI_CMD_CONTROL;
575                         ev[1] = _list->parameter().id();
576                         ev[2] = int(val);
577                         break;
578
579                 case MidiPgmChangeAutomation:
580                         size = 2;
581                         ev[0] += MIDI_CMD_PGM_CHANGE;
582                         ev[1] = int(val);
583                         break;
584
585                 case MidiChannelPressureAutomation:
586                         size = 2;
587                         ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
588                         ev[1] = int(val);
589                         break;
590
591                 case MidiPitchBenderAutomation:
592                         ev[0] += MIDI_CMD_BENDER;
593                         ev[1] = 0x7F & int(val);
594                         ev[2] = 0x7F & (int(val) >> 7);
595                         break;
596
597                 default:
598                         assert(false);
599                 }
600                 _route->write_immediate_event(size,  ev);
601         }
602
603         AutomationControl::set_value(val);
604 }
605
606 void
607 MidiTrack::set_step_editing (bool yn)
608 {
609         if (_session.record_status() != Session::Disabled) {
610                 return;
611         }
612
613         if (yn != _step_editing) {
614                 _step_editing = yn;
615                 StepEditStatusChange (yn);
616         }
617 }
618
619 void
620 MidiTrack::set_midi_thru (bool yn)
621 {
622         _midi_thru = yn;
623 }
624
625 boost::shared_ptr<SMFSource>
626 MidiTrack::write_source (uint32_t)
627 {
628         return midi_diskstream()->write_source ();
629 }
630
631 void
632 MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask)
633 {
634         midi_diskstream()->set_channel_mode (mode, mask);
635 }
636
637 ChannelMode
638 MidiTrack::get_channel_mode ()
639 {
640         return midi_diskstream()->get_channel_mode ();
641 }
642
643 uint16_t
644 MidiTrack::get_channel_mask ()
645 {
646         return midi_diskstream()->get_channel_mask ();
647 }
648
649 boost::shared_ptr<MidiPlaylist>
650 MidiTrack::midi_playlist ()
651 {
652         return midi_diskstream()->midi_playlist ();
653 }
654
655 void
656 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
657 {
658         DataRecorded (src); /* EMIT SIGNAL */
659 }
660
661 bool
662 MidiTrack::input_active () const
663 {
664         return _input_active;
665 }
666
667 void
668 MidiTrack::set_input_active (bool yn)
669 {
670         if (yn != _input_active) {
671                 _input_active = yn;
672                 map_input_active (yn);
673                 InputActiveChanged (); /* EMIT SIGNAL */
674         }
675 }
676
677 void
678 MidiTrack::map_input_active (bool yn)
679 {
680         if (!_input) {
681                 return;
682         }
683
684         PortSet& ports (_input->ports());
685
686         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
687                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
688                 if (yn != mp->input_active()) {
689                         mp->set_input_active (yn);
690                 }
691         }
692 }
693
694 void
695 MidiTrack::track_input_active (IOChange change, void* /* src */)
696 {
697         if (change.type & IOChange::ConfigurationChanged) {
698                 map_input_active (_input_active);
699         }
700 }
701
702 boost::shared_ptr<Diskstream>
703 MidiTrack::diskstream_factory (XMLNode const & node)
704 {
705         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
706 }
707
708 boost::shared_ptr<MidiBuffer>
709 MidiTrack::get_gui_feed_buffer () const
710 {
711         return midi_diskstream()->get_gui_feed_buffer ();
712 }
713
714 void
715 MidiTrack::act_on_mute ()
716 {
717         /* this is called right after our mute status has changed.
718            if we are now muted, send suitable output to shutdown
719            all our notes.
720
721            XXX we should should also stop all relevant note trackers.
722         */
723
724         if (muted()) {
725                 /* only send messages for channels we are using */
726
727                 uint16_t mask = get_channel_mask();
728
729                 for (uint8_t channel = 0; channel <= 0xF; channel++) {
730
731                         if ((1<<channel) & mask) {
732
733                                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
734                                 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
735                                 write_immediate_event (3, ev);
736                                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
737                                 write_immediate_event (3, ev);
738                         }
739                 }
740         }
741 }
742         
743 void
744 MidiTrack::set_monitoring (MonitorChoice mc)
745 {
746         Track::set_monitoring (mc);
747
748         boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
749
750         if (md) {
751                 md->reset_tracker ();
752         }
753 }
754
755 MonitorState
756 MidiTrack::monitoring_state () const
757 {
758         /* Explicit requests */
759         
760         if (_monitoring & MonitorInput) {
761                 return MonitoringInput;
762         }
763                 
764         if (_monitoring & MonitorDisk) {
765                 return MonitoringDisk;
766         }
767
768         if (_session.transport_rolling()) {
769                 return MonitoringDisk;
770         } 
771
772         /* the return value here doesn't mean that we're actually monitoring
773          * input, let alone input *audio*. but it means that we are NOT 
774          * monitoring silence. this allows us to still hear any audio generated
775          * by using internal generation techniques
776          */
777
778         return MonitoringInput;
779 }