f7f9ff7a596dc040c9e7dcc5dffbb82e21981dff
[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                 return 0;
323         }
324
325         boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
326
327         if (n_outputs().n_total() == 0 && _processors.empty()) {
328                 return 0;
329         }
330
331         if (!_active) {
332                 silence (nframes);
333                 return 0;
334         }
335
336         framepos_t transport_frame = _session.transport_frame();
337
338         int dret;
339         framecnt_t playback_distance;
340
341         if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
342                 /* need to do this so that the diskstream sets its
343                    playback distance to zero, thus causing diskstream::commit
344                    to do nothing.
345                    */
346                 BufferSet bufs; /* empty set - is OK, since nothing will happen */
347
348                 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
349                 need_butler = diskstream->commit (playback_distance);
350                 return dret;
351         }
352
353         BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
354
355         fill_buffers_with_input (bufs, _input, nframes);
356
357         if (_meter_point == MeterInput) {
358                 _meter->run (bufs, start_frame, end_frame, nframes, true);
359         }
360
361         /* filter captured data before the diskstream sees it */
362
363         filter_channels (bufs, get_capture_channel_mode(), get_capture_channel_mask());
364
365         _silent = false;
366
367         if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
368                 need_butler = diskstream->commit (playback_distance);
369                 silence (nframes);
370                 return dret;
371         }
372
373         /* filter playback data before we do anything else */
374         
375         filter_channels (bufs, get_playback_channel_mode(), get_playback_channel_mask ());
376
377         if (monitoring_state() == MonitoringInput) {
378
379                 /* not actually recording, but we want to hear the input material anyway,
380                    at least potentially (depending on monitoring options)
381                 */
382
383                 /* because the playback buffer is event based and not a
384                  * continuous stream, we need to make sure that we empty
385                  * it of events every cycle to avoid it filling up with events
386                  * read from disk, while we are actually monitoring input
387                  */
388
389                 diskstream->flush_playback (start_frame, end_frame);
390
391         } 
392
393         
394         /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
395         
396         write_out_of_band_data (bufs, start_frame, end_frame, nframes);
397         
398         /* final argument: don't waste time with automation if we're not recording or rolling */
399         
400         process_output_buffers (bufs, start_frame, end_frame, nframes,
401                                 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
402
403         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
404                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
405                 if (d) {
406                         d->flush_buffers (nframes);
407                 }
408         }
409
410         need_butler = diskstream->commit (playback_distance);
411         
412         return 0;
413 }
414
415 int
416 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
417 {
418         int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
419
420         if (ret == 0 && _step_editing) {
421                 push_midi_input_to_step_edit_ringbuffer (nframes);
422         }
423
424         return ret;
425 }
426
427 void
428 MidiTrack::realtime_locate ()
429 {
430         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
431
432         if (!lm.locked ()) {
433                 return;
434         }
435
436         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
437                 (*i)->realtime_locate ();
438         }
439
440         midi_diskstream()->reset_tracker ();
441 }
442
443 void
444 MidiTrack::realtime_handle_transport_stopped ()
445 {
446         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
447
448         if (!lm.locked ()) {
449                 return;
450         }
451
452         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
453                 (*i)->realtime_handle_transport_stopped ();
454         }
455 }
456
457 void
458 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
459 {
460         PortSet& ports (_input->ports());
461
462         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
463
464                 Buffer& b (p->get_buffer (nframes));
465                 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
466                 assert (mb);
467
468                 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
469
470                         const Evoral::MIDIEvent<framepos_t> ev(*e, false);
471
472                         /* note on, since for step edit, note length is determined
473                            elsewhere
474                         */
475
476                         if (ev.is_note_on()) {
477                                 /* we don't care about the time for this purpose */
478                                 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
479                         }
480                 }
481         }
482 }
483
484 void 
485 MidiTrack::filter_channels (BufferSet& bufs, ChannelMode mode, uint32_t mask)
486 {
487         if (mode == AllChannels) {
488                 return;
489         }
490
491         MidiBuffer& buf (bufs.get_midi (0));
492         
493         for (MidiBuffer::iterator e = buf.begin(); e != buf.end(); ) {
494                 
495                 Evoral::MIDIEvent<framepos_t> ev(*e, false);
496
497                 if (ev.is_channel_event()) {
498                         switch (mode) {
499                         case FilterChannels:
500                                 if (0 == ((1<<ev.channel()) & mask)) {
501                                         e = buf.erase (e);
502                                 } else {
503                                         ++e;
504                                 }
505                                 break;
506                         case ForceChannel:
507                                 ev.set_channel (ffs (mask) - 1);
508                                 ++e;
509                                 break;
510                         case AllChannels:
511                                 /* handled by the opening if() */
512                                 ++e;
513                                 break;
514                         }
515                 } else {
516                         ++e;
517                 }
518         }
519 }
520
521 void
522 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
523 {
524         MidiBuffer& buf (bufs.get_midi (0));
525
526         // Append immediate events
527
528         if (_immediate_events.read_space()) {
529
530                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
531                                                             name(), _immediate_events.read_space()));
532
533                 /* write as many of the immediate events as we can, but give "true" as
534                  * the last argument ("stop on overflow in destination") so that we'll
535                  * ship the rest out next time.
536                  *
537                  * the (nframes-1) argument puts all these events at the last
538                  * possible position of the output buffer, so that we do not
539                  * violate monotonicity when writing.
540                  */
541
542                 _immediate_events.read (buf, 0, 1, nframes-1, true);
543         }
544 }
545
546 int
547 MidiTrack::export_stuff (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framecnt_t /*nframes*/, 
548                          boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/, bool /*forexport*/)
549 {
550         return -1;
551 }
552
553 boost::shared_ptr<Region>
554 MidiTrack::bounce (InterThreadInfo& /*itt*/)
555 {
556         std::cerr << "MIDI bounce currently unsupported" << std::endl;
557         return boost::shared_ptr<Region> ();
558 }
559
560
561 boost::shared_ptr<Region>
562 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/,
563                          boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/)
564 {
565         std::cerr << "MIDI bounce range currently unsupported" << std::endl;
566         return boost::shared_ptr<Region> ();
567 }
568
569 void
570 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
571 {
572         std::cerr << "MIDI freeze currently unsupported" << std::endl;
573 }
574
575 void
576 MidiTrack::unfreeze ()
577 {
578         _freeze_record.state = UnFrozen;
579         FreezeChange (); /* EMIT SIGNAL */
580 }
581
582 void
583 MidiTrack::set_note_mode (NoteMode m)
584 {
585         _note_mode = m;
586         midi_diskstream()->set_note_mode(m);
587 }
588
589 std::string
590 MidiTrack::describe_parameter (Evoral::Parameter param)
591 {
592         const std::string str(instrument_info().get_controller_name(param));
593         return str.empty() ? Automatable::describe_parameter(param) : str;
594 }
595
596 void
597 MidiTrack::midi_panic()
598 {
599         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
600         for (uint8_t channel = 0; channel <= 0xF; channel++) {
601                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
602                 write_immediate_event(3, ev);
603                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
604                 write_immediate_event(3, ev);
605                 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
606                 write_immediate_event(3, ev);
607         }
608 }
609
610 /** \return true on success, false on failure (no buffer space left)
611  */
612 bool
613 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
614 {
615         if (!Evoral::midi_event_is_valid(buf, size)) {
616                 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
617                 return false;
618         }
619         const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
620         return (_immediate_events.write(0, type, size, buf) == size);
621 }
622
623 void
624 MidiTrack::MidiControl::set_value(double val)
625 {
626         bool valid = false;
627         if (std::isinf(val)) {
628                 cerr << "MIDIControl value is infinity" << endl;
629         } else if (std::isnan(val)) {
630                 cerr << "MIDIControl value is NaN" << endl;
631         } else if (val < _list->parameter().min()) {
632                 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
633         } else if (val > _list->parameter().max()) {
634                 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
635         } else {
636                 valid = true;
637         }
638
639         if (!valid) {
640                 return;
641         }
642
643         assert(val <= _list->parameter().max());
644         if ( ! automation_playback()) {
645                 size_t size = 3;
646                 uint8_t ev[3] = { _list->parameter().channel(), uint8_t (val), 0 };
647                 switch(_list->parameter().type()) {
648                 case MidiCCAutomation:
649                         ev[0] += MIDI_CMD_CONTROL;
650                         ev[1] = _list->parameter().id();
651                         ev[2] = int(val);
652                         break;
653
654                 case MidiPgmChangeAutomation:
655                         size = 2;
656                         ev[0] += MIDI_CMD_PGM_CHANGE;
657                         ev[1] = int(val);
658                         break;
659
660                 case MidiChannelPressureAutomation:
661                         size = 2;
662                         ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
663                         ev[1] = int(val);
664                         break;
665
666                 case MidiPitchBenderAutomation:
667                         ev[0] += MIDI_CMD_BENDER;
668                         ev[1] = 0x7F & int(val);
669                         ev[2] = 0x7F & (int(val) >> 7);
670                         break;
671
672                 default:
673                         assert(false);
674                 }
675                 _route->write_immediate_event(size,  ev);
676         }
677
678         AutomationControl::set_value(val);
679 }
680
681 void
682 MidiTrack::set_step_editing (bool yn)
683 {
684         if (_session.record_status() != Session::Disabled) {
685                 return;
686         }
687
688         if (yn != _step_editing) {
689                 _step_editing = yn;
690                 StepEditStatusChange (yn);
691         }
692 }
693
694 boost::shared_ptr<SMFSource>
695 MidiTrack::write_source (uint32_t)
696 {
697         return midi_diskstream()->write_source ();
698 }
699
700 void
701 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask) 
702 {
703         ChannelMode old = get_playback_channel_mode ();
704         uint16_t old_mask = get_playback_channel_mask ();
705
706         if (old != mode || mask != old_mask) {
707                 _set_playback_channel_mode (mode, mask);
708                 PlaybackChannelModeChanged ();
709                 _session.set_dirty ();
710         }
711 }
712
713 void
714 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask) 
715 {
716         ChannelMode old = get_capture_channel_mode ();
717         uint16_t old_mask = get_capture_channel_mask ();
718
719         if (old != mode || mask != old_mask) {
720                 _set_capture_channel_mode (mode, mask);
721                 CaptureChannelModeChanged ();
722                 _session.set_dirty ();
723         }
724 }
725
726 void
727 MidiTrack::set_playback_channel_mask (uint16_t mask)
728 {
729         uint16_t old = get_playback_channel_mask();
730
731         if (old != mask) {
732                 _set_playback_channel_mask (mask);
733                 PlaybackChannelMaskChanged ();
734                 _session.set_dirty ();
735         }
736 }
737
738 void
739 MidiTrack::set_capture_channel_mask (uint16_t mask)
740 {
741         uint16_t old = get_capture_channel_mask();
742
743         if (old != mask) {
744                 _set_capture_channel_mask (mask);
745                 CaptureChannelMaskChanged ();
746                 _session.set_dirty ();
747         }
748 }
749
750 boost::shared_ptr<MidiPlaylist>
751 MidiTrack::midi_playlist ()
752 {
753         return midi_diskstream()->midi_playlist ();
754 }
755
756 void
757 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
758 {
759         DataRecorded (src); /* EMIT SIGNAL */
760 }
761
762 bool
763 MidiTrack::input_active () const
764 {
765         return _input_active;
766 }
767
768 void
769 MidiTrack::set_input_active (bool yn)
770 {
771         if (yn != _input_active) {
772                 _input_active = yn;
773                 map_input_active (yn);
774                 InputActiveChanged (); /* EMIT SIGNAL */
775         }
776 }
777
778 void
779 MidiTrack::map_input_active (bool yn)
780 {
781         if (!_input) {
782                 return;
783         }
784
785         PortSet& ports (_input->ports());
786
787         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
788                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
789                 if (yn != mp->input_active()) {
790                         mp->set_input_active (yn);
791                 }
792         }
793 }
794
795 void
796 MidiTrack::track_input_active (IOChange change, void* /* src */)
797 {
798         if (change.type & IOChange::ConfigurationChanged) {
799                 map_input_active (_input_active);
800         }
801 }
802
803 boost::shared_ptr<Diskstream>
804 MidiTrack::diskstream_factory (XMLNode const & node)
805 {
806         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
807 }
808
809 boost::shared_ptr<MidiBuffer>
810 MidiTrack::get_gui_feed_buffer () const
811 {
812         return midi_diskstream()->get_gui_feed_buffer ();
813 }
814
815 void
816 MidiTrack::act_on_mute ()
817 {
818         /* this is called right after our mute status has changed.
819            if we are now muted, send suitable output to shutdown
820            all our notes.
821
822            XXX we should should also stop all relevant note trackers.
823         */
824
825         /* If we haven't got a diskstream yet, there's nothing to worry about,
826            and we can't call get_channel_mask() anyway.
827         */
828         if (!midi_diskstream()) {
829                 return;
830         }
831
832         if (muted()) {
833                 /* only send messages for channels we are using */
834
835                 uint16_t mask = get_playback_channel_mask();
836
837                 for (uint8_t channel = 0; channel <= 0xF; channel++) {
838
839                         if ((1<<channel) & mask) {
840
841                                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
842                                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
843                                 write_immediate_event (3, ev);
844                                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
845                                 write_immediate_event (3, ev);
846                         }
847                 }
848         }
849 }
850         
851 void
852 MidiTrack::set_monitoring (MonitorChoice mc)
853 {
854         if (mc != _monitoring) {
855
856                 Track::set_monitoring (mc);
857                 
858                 /* monitoring state changed, so flush out any on notes at the
859                  * port level.
860                  */
861
862                 PortSet& ports (_output->ports());
863                 
864                 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
865                         boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
866                         if (mp) {
867                                 mp->require_resolve ();
868                         }
869                 }
870
871                 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
872                 
873                 if (md) {
874                         md->reset_tracker ();
875                 }
876         }
877 }
878
879 MonitorState
880 MidiTrack::monitoring_state () const
881 {
882         MonitorState ms = Track::monitoring_state();
883         if (ms == MonitoringSilence) {
884                 return MonitoringInput;
885         } 
886         return ms;
887 }
888