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