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