Save LV2 presets with relative URIs to their own bundle, in the same style as Jalv.
[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
356                  * single-MIDI-channel diskstream 
357                  */
358                 ChanCount c;
359                 c.set_audio (0);
360                 c.set_midi (1);
361                 bufs.set_count (c);
362
363                 assert (nframes > 0);
364
365                 diskstream->get_playback (mbuf, nframes);
366
367                 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
368
369                 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
370
371                 /* final argument: don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
372
373                 process_output_buffers (
374                         bufs, start_frame, end_frame, nframes,
375                         declick, (!diskstream->record_enabled() && !_session.transport_stopped())
376                         );
377         }
378
379         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
380                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
381                 if (d) {
382                         d->flush_buffers (nframes);
383                 }
384         }
385
386         need_butler = diskstream->commit (playback_distance);
387         
388         return 0;
389 }
390
391 int
392 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
393 {
394         int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
395
396         if (ret == 0 && _step_editing) {
397                 push_midi_input_to_step_edit_ringbuffer (nframes);
398         }
399
400         return ret;
401 }
402
403 void
404 MidiTrack::realtime_locate ()
405 {
406         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
407
408         if (!lm.locked ()) {
409                 return;
410         }
411
412         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
413                 (*i)->realtime_locate ();
414         }
415
416         midi_diskstream()->reset_tracker ();
417 }
418
419 void
420 MidiTrack::realtime_handle_transport_stopped ()
421 {
422         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
423
424         if (!lm.locked ()) {
425                 return;
426         }
427
428         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
429                 (*i)->realtime_handle_transport_stopped ();
430         }
431 }
432
433 void
434 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
435 {
436         PortSet& ports (_input->ports());
437
438         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
439
440                 Buffer& b (p->get_buffer (nframes));
441                 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
442                 assert (mb);
443
444                 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
445
446                         const Evoral::MIDIEvent<framepos_t> ev(*e, false);
447
448                         /* note on, since for step edit, note length is determined
449                            elsewhere
450                         */
451
452                         if (ev.is_note_on()) {
453                                 /* we don't care about the time for this purpose */
454                                 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
455                         }
456                 }
457         }
458 }
459
460 void
461 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
462 {
463         MidiBuffer& buf (bufs.get_midi (0));
464
465         // Append immediate events
466
467         if (_immediate_events.read_space()) {
468
469                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
470                                                             name(), _immediate_events.read_space()));
471
472                 /* write as many of the immediate events as we can, but give "true" as
473                  * the last argument ("stop on overflow in destination") so that we'll
474                  * ship the rest out next time.
475                  *
476                  * the (nframes-1) argument puts all these events at the last
477                  * possible position of the output buffer, so that we do not
478                  * violate monotonicity when writing.
479                  */
480
481                 _immediate_events.read (buf, 0, 1, nframes-1, true);
482         }
483 }
484
485 int
486 MidiTrack::export_stuff (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framecnt_t /*nframes*/, 
487                          boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/, bool /*forexport*/)
488 {
489         return -1;
490 }
491
492 boost::shared_ptr<Region>
493 MidiTrack::bounce (InterThreadInfo& /*itt*/)
494 {
495         std::cerr << "MIDI bounce currently unsupported" << std::endl;
496         return boost::shared_ptr<Region> ();
497 }
498
499
500 boost::shared_ptr<Region>
501 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/,
502                          boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/)
503 {
504         std::cerr << "MIDI bounce range currently unsupported" << std::endl;
505         return boost::shared_ptr<Region> ();
506 }
507
508 void
509 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
510 {
511         std::cerr << "MIDI freeze currently unsupported" << std::endl;
512 }
513
514 void
515 MidiTrack::unfreeze ()
516 {
517         _freeze_record.state = UnFrozen;
518         FreezeChange (); /* EMIT SIGNAL */
519 }
520
521 void
522 MidiTrack::set_note_mode (NoteMode m)
523 {
524         _note_mode = m;
525         midi_diskstream()->set_note_mode(m);
526 }
527
528 std::string
529 MidiTrack::describe_parameter (Evoral::Parameter param)
530 {
531         const std::string str(instrument_info().get_controller_name(param));
532         return str.empty() ? Automatable::describe_parameter(param) : str;
533 }
534
535 void
536 MidiTrack::midi_panic()
537 {
538         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
539         for (uint8_t channel = 0; channel <= 0xF; channel++) {
540                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
541                 write_immediate_event(3, ev);
542                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
543                 write_immediate_event(3, ev);
544                 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
545                 write_immediate_event(3, ev);
546         }
547 }
548
549 /** \return true on success, false on failure (no buffer space left)
550  */
551 bool
552 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
553 {
554         if (!Evoral::midi_event_is_valid(buf, size)) {
555                 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
556                 return false;
557         }
558         const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
559         return (_immediate_events.write(0, type, size, buf) == size);
560 }
561
562 void
563 MidiTrack::MidiControl::set_value(double val)
564 {
565         bool valid = false;
566         if (std::isinf(val)) {
567                 cerr << "MIDIControl value is infinity" << endl;
568         } else if (std::isnan(val)) {
569                 cerr << "MIDIControl value is NaN" << endl;
570         } else if (val < _list->parameter().min()) {
571                 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
572         } else if (val > _list->parameter().max()) {
573                 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
574         } else {
575                 valid = true;
576         }
577
578         if (!valid) {
579                 return;
580         }
581
582         assert(val <= _list->parameter().max());
583         if ( ! automation_playback()) {
584                 size_t size = 3;
585                 uint8_t ev[3] = { _list->parameter().channel(), uint8_t (val), 0 };
586                 switch(_list->parameter().type()) {
587                 case MidiCCAutomation:
588                         ev[0] += MIDI_CMD_CONTROL;
589                         ev[1] = _list->parameter().id();
590                         ev[2] = int(val);
591                         break;
592
593                 case MidiPgmChangeAutomation:
594                         size = 2;
595                         ev[0] += MIDI_CMD_PGM_CHANGE;
596                         ev[1] = int(val);
597                         break;
598
599                 case MidiChannelPressureAutomation:
600                         size = 2;
601                         ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
602                         ev[1] = int(val);
603                         break;
604
605                 case MidiPitchBenderAutomation:
606                         ev[0] += MIDI_CMD_BENDER;
607                         ev[1] = 0x7F & int(val);
608                         ev[2] = 0x7F & (int(val) >> 7);
609                         break;
610
611                 default:
612                         assert(false);
613                 }
614                 _route->write_immediate_event(size,  ev);
615         }
616
617         AutomationControl::set_value(val);
618 }
619
620 void
621 MidiTrack::set_step_editing (bool yn)
622 {
623         if (_session.record_status() != Session::Disabled) {
624                 return;
625         }
626
627         if (yn != _step_editing) {
628                 _step_editing = yn;
629                 StepEditStatusChange (yn);
630         }
631 }
632
633 boost::shared_ptr<SMFSource>
634 MidiTrack::write_source (uint32_t)
635 {
636         return midi_diskstream()->write_source ();
637 }
638
639 void
640 MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask)
641 {
642         midi_diskstream()->set_channel_mode (mode, mask);
643 }
644
645 ChannelMode
646 MidiTrack::get_channel_mode ()
647 {
648         return midi_diskstream()->get_channel_mode ();
649 }
650
651 uint16_t
652 MidiTrack::get_channel_mask ()
653 {
654         return midi_diskstream()->get_channel_mask ();
655 }
656
657 boost::shared_ptr<MidiPlaylist>
658 MidiTrack::midi_playlist ()
659 {
660         return midi_diskstream()->midi_playlist ();
661 }
662
663 void
664 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
665 {
666         DataRecorded (src); /* EMIT SIGNAL */
667 }
668
669 bool
670 MidiTrack::input_active () const
671 {
672         return _input_active;
673 }
674
675 void
676 MidiTrack::set_input_active (bool yn)
677 {
678         if (yn != _input_active) {
679                 _input_active = yn;
680                 map_input_active (yn);
681                 InputActiveChanged (); /* EMIT SIGNAL */
682         }
683 }
684
685 void
686 MidiTrack::map_input_active (bool yn)
687 {
688         if (!_input) {
689                 return;
690         }
691
692         PortSet& ports (_input->ports());
693
694         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
695                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
696                 if (yn != mp->input_active()) {
697                         mp->set_input_active (yn);
698                 }
699         }
700 }
701
702 void
703 MidiTrack::track_input_active (IOChange change, void* /* src */)
704 {
705         if (change.type & IOChange::ConfigurationChanged) {
706                 map_input_active (_input_active);
707         }
708 }
709
710 boost::shared_ptr<Diskstream>
711 MidiTrack::diskstream_factory (XMLNode const & node)
712 {
713         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
714 }
715
716 boost::shared_ptr<MidiBuffer>
717 MidiTrack::get_gui_feed_buffer () const
718 {
719         return midi_diskstream()->get_gui_feed_buffer ();
720 }
721
722 void
723 MidiTrack::act_on_mute ()
724 {
725         /* this is called right after our mute status has changed.
726            if we are now muted, send suitable output to shutdown
727            all our notes.
728
729            XXX we should should also stop all relevant note trackers.
730         */
731
732         /* If we haven't got a diskstream yet, there's nothing to worry about,
733            and we can't call get_channel_mask() anyway.
734         */
735         if (!midi_diskstream()) {
736                 return;
737         }
738
739         if (muted()) {
740                 /* only send messages for channels we are using */
741
742                 uint16_t mask = get_channel_mask();
743
744                 for (uint8_t channel = 0; channel <= 0xF; channel++) {
745
746                         if ((1<<channel) & mask) {
747
748                                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
749                                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
750                                 write_immediate_event (3, ev);
751                                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
752                                 write_immediate_event (3, ev);
753                         }
754                 }
755         }
756 }
757         
758 void
759 MidiTrack::set_monitoring (MonitorChoice mc)
760 {
761         if (mc != _monitoring) {
762
763                 Track::set_monitoring (mc);
764                 
765                 /* monitoring state changed, so flush out any on notes at the
766                  * port level.
767                  */
768
769                 PortSet& ports (_output->ports());
770                 
771                 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
772                         boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
773                         if (mp) {
774                                 mp->require_resolve ();
775                         }
776                 }
777
778                 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
779                 
780                 if (md) {
781                         md->reset_tracker ();
782                 }
783         }
784 }
785
786 MonitorState
787 MidiTrack::monitoring_state () const
788 {
789         MonitorState ms = Track::monitoring_state();
790         if (ms == MonitoringSilence) {
791                 return MonitoringInput;
792         } 
793         return ms;
794 }