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