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