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