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