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