radically rethink export/bounce/freeze code design. probably not 100% done by freeze...
[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                          boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/, bool /*forexport*/)
483 {
484         return -1;
485 }
486
487 boost::shared_ptr<Region>
488 MidiTrack::bounce (InterThreadInfo& /*itt*/)
489 {
490         std::cerr << "MIDI bounce currently unsupported" << std::endl;
491         return boost::shared_ptr<Region> ();
492 }
493
494
495 boost::shared_ptr<Region>
496 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/,
497                          boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/)
498 {
499         std::cerr << "MIDI bounce range currently unsupported" << std::endl;
500         return boost::shared_ptr<Region> ();
501 }
502
503 void
504 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
505 {
506         std::cerr << "MIDI freeze currently unsupported" << std::endl;
507 }
508
509 void
510 MidiTrack::unfreeze ()
511 {
512         _freeze_record.state = UnFrozen;
513         FreezeChange (); /* EMIT SIGNAL */
514 }
515
516 void
517 MidiTrack::set_note_mode (NoteMode m)
518 {
519         _note_mode = m;
520         midi_diskstream()->set_note_mode(m);
521 }
522
523 void
524 MidiTrack::midi_panic()
525 {
526         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
527         for (uint8_t channel = 0; channel <= 0xF; channel++) {
528                 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
529                 write_immediate_event(3, ev);
530                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
531                 write_immediate_event(3, ev);
532                 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
533                 write_immediate_event(3, ev);
534         }
535 }
536
537 /** \return true on success, false on failure (no buffer space left)
538  */
539 bool
540 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
541 {
542         if (!Evoral::midi_event_is_valid(buf, size)) {
543                 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
544                 return false;
545         }
546         const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
547         return (_immediate_events.write(0, type, size, buf) == size);
548 }
549
550 void
551 MidiTrack::MidiControl::set_value(double val)
552 {
553         bool valid = false;
554         if (isinf(val)) {
555                 cerr << "MIDIControl value is infinity" << endl;
556         } else if (isnan(val)) {
557                 cerr << "MIDIControl value is NaN" << endl;
558         } else if (val < _list->parameter().min()) {
559                 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
560         } else if (val > _list->parameter().max()) {
561                 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
562         } else {
563                 valid = true;
564         }
565
566         if (!valid) {
567                 return;
568         }
569
570         assert(val <= _list->parameter().max());
571         if ( ! automation_playback()) {
572                 size_t size = 3;
573                 uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
574                 switch(_list->parameter().type()) {
575                 case MidiCCAutomation:
576                         ev[0] += MIDI_CMD_CONTROL;
577                         ev[1] = _list->parameter().id();
578                         ev[2] = int(val);
579                         break;
580
581                 case MidiPgmChangeAutomation:
582                         size = 2;
583                         ev[0] += MIDI_CMD_PGM_CHANGE;
584                         ev[1] = int(val);
585                         break;
586
587                 case MidiChannelPressureAutomation:
588                         size = 2;
589                         ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
590                         ev[1] = int(val);
591                         break;
592
593                 case MidiPitchBenderAutomation:
594                         ev[0] += MIDI_CMD_BENDER;
595                         ev[1] = 0x7F & int(val);
596                         ev[2] = 0x7F & (int(val) >> 7);
597                         break;
598
599                 default:
600                         assert(false);
601                 }
602                 _route->write_immediate_event(size,  ev);
603         }
604
605         AutomationControl::set_value(val);
606 }
607
608 void
609 MidiTrack::set_step_editing (bool yn)
610 {
611         if (_session.record_status() != Session::Disabled) {
612                 return;
613         }
614
615         if (yn != _step_editing) {
616                 _step_editing = yn;
617                 StepEditStatusChange (yn);
618         }
619 }
620
621 void
622 MidiTrack::set_midi_thru (bool yn)
623 {
624         _midi_thru = yn;
625 }
626
627 boost::shared_ptr<SMFSource>
628 MidiTrack::write_source (uint32_t)
629 {
630         return midi_diskstream()->write_source ();
631 }
632
633 void
634 MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask)
635 {
636         midi_diskstream()->set_channel_mode (mode, mask);
637 }
638
639 ChannelMode
640 MidiTrack::get_channel_mode ()
641 {
642         return midi_diskstream()->get_channel_mode ();
643 }
644
645 uint16_t
646 MidiTrack::get_channel_mask ()
647 {
648         return midi_diskstream()->get_channel_mask ();
649 }
650
651 boost::shared_ptr<MidiPlaylist>
652 MidiTrack::midi_playlist ()
653 {
654         return midi_diskstream()->midi_playlist ();
655 }
656
657 void
658 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
659 {
660         DataRecorded (src); /* EMIT SIGNAL */
661 }
662
663 bool
664 MidiTrack::input_active () const
665 {
666         return _input_active;
667 }
668
669 void
670 MidiTrack::set_input_active (bool yn)
671 {
672         if (yn != _input_active) {
673                 _input_active = yn;
674                 map_input_active (yn);
675                 InputActiveChanged (); /* EMIT SIGNAL */
676         }
677 }
678
679 void
680 MidiTrack::map_input_active (bool yn)
681 {
682         if (!_input) {
683                 return;
684         }
685
686         PortSet& ports (_input->ports());
687
688         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
689                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
690                 if (yn != mp->input_active()) {
691                         mp->set_input_active (yn);
692                 }
693         }
694 }
695
696 void
697 MidiTrack::track_input_active (IOChange change, void* /* src */)
698 {
699         if (change.type & IOChange::ConfigurationChanged) {
700                 map_input_active (_input_active);
701         }
702 }
703
704 boost::shared_ptr<Diskstream>
705 MidiTrack::diskstream_factory (XMLNode const & node)
706 {
707         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
708 }
709
710 boost::shared_ptr<MidiBuffer>
711 MidiTrack::get_gui_feed_buffer () const
712 {
713         return midi_diskstream()->get_gui_feed_buffer ();
714 }
715
716 void
717 MidiTrack::act_on_mute ()
718 {
719         /* this is called right after our mute status has changed.
720            if we are now muted, send suitable output to shutdown
721            all our notes.
722
723            XXX we should should also stop all relevant note trackers.
724         */
725
726         if (muted()) {
727                 /* only send messages for channels we are using */
728
729                 uint16_t mask = get_channel_mask();
730
731                 for (uint8_t channel = 0; channel <= 0xF; channel++) {
732
733                         if ((1<<channel) & mask) {
734
735                                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
736                                 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
737                                 write_immediate_event (3, ev);
738                                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
739                                 write_immediate_event (3, ev);
740                         }
741                 }
742         }
743 }
744         
745 void
746 MidiTrack::set_monitoring (MonitorChoice mc)
747 {
748         Track::set_monitoring (mc);
749
750         boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
751
752         if (md) {
753                 md->reset_tracker ();
754         }
755 }
756
757 MonitorState
758 MidiTrack::monitoring_state () const
759 {
760         /* Explicit requests */
761         
762         if (_monitoring & MonitorInput) {
763                 return MonitoringInput;
764         }
765                 
766         if (_monitoring & MonitorDisk) {
767                 return MonitoringDisk;
768         }
769
770         if (_session.transport_rolling()) {
771                 return MonitoringDisk;
772         } 
773
774         /* the return value here doesn't mean that we're actually monitoring
775          * input, let alone input *audio*. but it means that we are NOT 
776          * monitoring silence. this allows us to still hear any audio generated
777          * by using internal generation techniques
778          */
779
780         return MonitoringInput;
781 }