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