first vaguely working version using PresentationInfo
[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 "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         if (_mute_control->list() && _mute_control->automation_playback()) {
400                 bool        valid = false;
401                 const float mute  = _mute_control->list()->rt_safe_eval(transport_frame, valid);
402                 if (mute >= 0.5 && !muted()) {
403                         _mute_control->set_value_unchecked(1.0);  // mute
404                 } else if (mute < 0.5 && muted()) {
405                         _mute_control->set_value_unchecked(0.0);  // unmute
406                 }
407         }
408
409         BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
410
411         fill_buffers_with_input (bufs, _input, nframes);
412
413         /* filter captured data before meter sees it */
414         _capture_filter.filter (bufs);
415
416         if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
417                 _meter->run (bufs, start_frame, end_frame, nframes, true);
418         }
419
420
421         _silent = false;
422
423         if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
424                 need_butler = diskstream->commit (playback_distance);
425                 silence (nframes);
426                 return dret;
427         }
428
429         /* note diskstream uses our filter to filter/map playback channels appropriately. */
430
431         if (monitoring_state() == MonitoringInput) {
432
433                 /* not actually recording, but we want to hear the input material anyway,
434                    at least potentially (depending on monitoring options)
435                 */
436
437                 /* because the playback buffer is event based and not a
438                  * continuous stream, we need to make sure that we empty
439                  * it of events every cycle to avoid it filling up with events
440                  * read from disk, while we are actually monitoring input
441                  */
442
443                 diskstream->flush_playback (start_frame, end_frame);
444
445         }
446
447
448         /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
449
450         write_out_of_band_data (bufs, start_frame, end_frame, nframes);
451
452         /* final argument: don't waste time with automation if we're not recording or rolling */
453
454         process_output_buffers (bufs, start_frame, end_frame, nframes,
455                                 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
456
457         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
458                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
459                 if (d) {
460                         d->flush_buffers (nframes);
461                 }
462         }
463
464         need_butler = diskstream->commit (playback_distance);
465
466         return 0;
467 }
468
469 int
470 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
471 {
472         int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
473
474         if (ret == 0 && _step_editing) {
475                 push_midi_input_to_step_edit_ringbuffer (nframes);
476         }
477
478         return ret;
479 }
480
481 void
482 MidiTrack::realtime_locate ()
483 {
484         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
485
486         if (!lm.locked ()) {
487                 return;
488         }
489
490         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
491                 (*i)->realtime_locate ();
492         }
493
494         midi_diskstream()->reset_tracker ();
495 }
496
497 void
498 MidiTrack::realtime_handle_transport_stopped ()
499 {
500         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
501
502         if (!lm.locked ()) {
503                 return;
504         }
505
506         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
507                 (*i)->realtime_handle_transport_stopped ();
508         }
509 }
510
511 void
512 MidiTrack::non_realtime_locate (framepos_t pos)
513 {
514         Track::non_realtime_locate(pos);
515
516         boost::shared_ptr<MidiPlaylist> playlist = midi_diskstream()->midi_playlist();
517         if (!playlist) {
518                 return;
519         }
520
521         /* Get the top unmuted region at this position. */
522         boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(
523                 playlist->top_unmuted_region_at(pos));
524         if (!region) {
525                 return;
526         }
527
528         /* the source may be missing, but the control still referenced in the GUI */
529         if (!region->midi_source() || !region->model()) {
530                 return;
531         }
532
533         Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK);
534         if (!lm.locked()) {
535                 return;
536         }
537
538         /* Update track controllers based on its "automation". */
539         const framepos_t     origin = region->position() - region->start();
540         BeatsFramesConverter bfc(_session.tempo_map(), origin);
541         for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
542                 boost::shared_ptr<MidiTrack::MidiControl> tcontrol;
543                 boost::shared_ptr<Evoral::Control>        rcontrol;
544                 if ((tcontrol = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) &&
545                     (rcontrol = region->control(tcontrol->parameter()))) {
546                         const Evoral::Beats pos_beats = bfc.from(pos - origin);
547                         if (rcontrol->list()->size() > 0) {
548                                 tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()), Controllable::NoGroup);
549                         }
550                 }
551         }
552 }
553
554 void
555 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
556 {
557         PortSet& ports (_input->ports());
558
559         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
560
561                 Buffer& b (p->get_buffer (nframes));
562                 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
563                 assert (mb);
564
565                 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
566
567                         const Evoral::MIDIEvent<framepos_t> ev(*e, false);
568
569                         /* note on, since for step edit, note length is determined
570                            elsewhere
571                         */
572
573                         if (ev.is_note_on()) {
574                                 /* we don't care about the time for this purpose */
575                                 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
576                         }
577                 }
578         }
579 }
580
581 void
582 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
583 {
584         MidiBuffer& buf (bufs.get_midi (0));
585
586         update_controls (bufs);
587
588         // Append immediate events
589
590         if (_immediate_events.read_space()) {
591
592                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
593                                                             name(), _immediate_events.read_space()));
594
595                 /* write as many of the immediate events as we can, but give "true" as
596                  * the last argument ("stop on overflow in destination") so that we'll
597                  * ship the rest out next time.
598                  *
599                  * the Port::port_offset() + (nframes-1) argument puts all these events at the last
600                  * possible position of the output buffer, so that we do not
601                  * violate monotonicity when writing. Port::port_offset() will
602                  * be non-zero if we're in a split process cycle.
603                  */
604                 _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
605         }
606 }
607
608 int
609 MidiTrack::export_stuff (BufferSet&                   buffers,
610                          framepos_t                   start,
611                          framecnt_t                   nframes,
612                          boost::shared_ptr<Processor> endpoint,
613                          bool                         include_endpoint,
614                          bool                         for_export,
615                          bool                         for_freeze)
616 {
617         if (buffers.count().n_midi() == 0) {
618                 return -1;
619         }
620
621         boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
622
623         Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
624
625         boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist>(diskstream->playlist());
626         if (!mpl) {
627                 return -2;
628         }
629
630         buffers.get_midi(0).clear();
631         if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) {
632                 return -1;
633         }
634
635         //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
636
637         return 0;
638 }
639
640 boost::shared_ptr<Region>
641 MidiTrack::bounce (InterThreadInfo& itt)
642 {
643         return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false);
644 }
645
646 boost::shared_ptr<Region>
647 MidiTrack::bounce_range (framepos_t                   start,
648                          framepos_t                   end,
649                          InterThreadInfo&             itt,
650                          boost::shared_ptr<Processor> endpoint,
651                          bool                         include_endpoint)
652 {
653         vector<boost::shared_ptr<Source> > srcs;
654         return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
655 }
656
657 void
658 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
659 {
660         std::cerr << "MIDI freeze currently unsupported" << std::endl;
661 }
662
663 void
664 MidiTrack::unfreeze ()
665 {
666         _freeze_record.state = UnFrozen;
667         FreezeChange (); /* EMIT SIGNAL */
668 }
669
670 void
671 MidiTrack::set_note_mode (NoteMode m)
672 {
673         _note_mode = m;
674         midi_diskstream()->set_note_mode(m);
675 }
676
677 std::string
678 MidiTrack::describe_parameter (Evoral::Parameter param)
679 {
680         const std::string str(instrument_info().get_controller_name(param));
681         return str.empty() ? Automatable::describe_parameter(param) : str;
682 }
683
684 void
685 MidiTrack::midi_panic()
686 {
687         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
688         for (uint8_t channel = 0; channel <= 0xF; channel++) {
689                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
690                 write_immediate_event(3, ev);
691                 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
692                 write_immediate_event(3, ev);
693                 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
694                 write_immediate_event(3, ev);
695         }
696 }
697
698 /** \return true on success, false on failure (no buffer space left)
699  */
700 bool
701 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
702 {
703         if (!Evoral::midi_event_is_valid(buf, size)) {
704                 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
705                 return false;
706         }
707         const uint32_t type = midi_parameter_type(buf[0]);
708         return (_immediate_events.write (0, type, 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 MidiSystemExclusiveAutomation:
720                 /* The track control for MIDI parameters is for immediate events to act
721                    as a control surface, write/touch for them is not currently
722                    supported. */
723                 return;
724         default:
725                 Automatable::set_parameter_automation_state(param, state);
726         }
727 }
728
729 void
730 MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
731 {
732         const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
733         const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
734
735         bool valid = false;
736         if (isinf_local(val)) {
737                 cerr << "MIDIControl value is infinity" << endl;
738         } else if (isnan_local(val)) {
739                 cerr << "MIDIControl value is NaN" << endl;
740         } else if (val < desc.lower) {
741                 cerr << "MIDIControl value is < " << desc.lower << endl;
742         } else if (val > desc.upper) {
743                 cerr << "MIDIControl value is > " << desc.upper << endl;
744         } else {
745                 valid = true;
746         }
747
748         if (!valid) {
749                 return;
750         }
751
752         assert(val <= desc.upper);
753         if ( ! _list || ! automation_playback()) {
754                 size_t size = 3;
755                 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
756                 switch(parameter.type()) {
757                 case MidiCCAutomation:
758                         ev[0] += MIDI_CMD_CONTROL;
759                         ev[1] = parameter.id();
760                         ev[2] = int(val);
761                         break;
762
763                 case MidiPgmChangeAutomation:
764                         size = 2;
765                         ev[0] += MIDI_CMD_PGM_CHANGE;
766                         ev[1] = int(val);
767                         break;
768
769                 case MidiChannelPressureAutomation:
770                         size = 2;
771                         ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
772                         ev[1] = int(val);
773                         break;
774
775                 case MidiPitchBenderAutomation:
776                         ev[0] += MIDI_CMD_BENDER;
777                         ev[1] = 0x7F & int(val);
778                         ev[2] = 0x7F & (int(val) >> 7);
779                         break;
780
781                 default:
782                         assert(false);
783                 }
784                 _route->write_immediate_event(size,  ev);
785         }
786
787         AutomationControl::actually_set_value(val, group_override);
788 }
789
790 void
791 MidiTrack::set_step_editing (bool yn)
792 {
793         if (_session.record_status() != Session::Disabled) {
794                 return;
795         }
796
797         if (yn != _step_editing) {
798                 _step_editing = yn;
799                 StepEditStatusChange (yn);
800         }
801 }
802
803 boost::shared_ptr<SMFSource>
804 MidiTrack::write_source (uint32_t)
805 {
806         return midi_diskstream()->write_source ();
807 }
808
809 void
810 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
811 {
812         if (_playback_filter.set_channel_mode(mode, mask)) {
813                 _session.set_dirty();
814         }
815 }
816
817 void
818 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
819 {
820         if (_capture_filter.set_channel_mode(mode, mask)) {
821                 _session.set_dirty();
822         }
823 }
824
825 void
826 MidiTrack::set_playback_channel_mask (uint16_t mask)
827 {
828         if (_playback_filter.set_channel_mask(mask)) {
829                 _session.set_dirty();
830         }
831 }
832
833 void
834 MidiTrack::set_capture_channel_mask (uint16_t mask)
835 {
836         if (_capture_filter.set_channel_mask(mask)) {
837                 _session.set_dirty();
838         }
839 }
840
841 boost::shared_ptr<MidiPlaylist>
842 MidiTrack::midi_playlist ()
843 {
844         return midi_diskstream()->midi_playlist ();
845 }
846
847 void
848 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
849 {
850         DataRecorded (src); /* EMIT SIGNAL */
851 }
852
853 bool
854 MidiTrack::input_active () const
855 {
856         return _input_active;
857 }
858
859 void
860 MidiTrack::set_input_active (bool yn)
861 {
862         if (yn != _input_active) {
863                 _input_active = yn;
864                 map_input_active (yn);
865                 InputActiveChanged (); /* EMIT SIGNAL */
866         }
867 }
868
869 void
870 MidiTrack::map_input_active (bool yn)
871 {
872         if (!_input) {
873                 return;
874         }
875
876         PortSet& ports (_input->ports());
877
878         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
879                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
880                 if (yn != mp->input_active()) {
881                         mp->set_input_active (yn);
882                 }
883         }
884 }
885
886 void
887 MidiTrack::track_input_active (IOChange change, void* /* src */)
888 {
889         if (change.type & IOChange::ConfigurationChanged) {
890                 map_input_active (_input_active);
891         }
892 }
893
894 boost::shared_ptr<Diskstream>
895 MidiTrack::diskstream_factory (XMLNode const & node)
896 {
897         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
898 }
899
900 boost::shared_ptr<MidiBuffer>
901 MidiTrack::get_gui_feed_buffer () const
902 {
903         return midi_diskstream()->get_gui_feed_buffer ();
904 }
905
906 void
907 MidiTrack::act_on_mute ()
908 {
909         /* this is called right after our mute status has changed.
910            if we are now muted, send suitable output to shutdown
911            all our notes.
912
913            XXX we should should also stop all relevant note trackers.
914         */
915
916         /* If we haven't got a diskstream yet, there's nothing to worry about,
917            and we can't call get_channel_mask() anyway.
918         */
919         if (!midi_diskstream()) {
920                 return;
921         }
922
923         if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) {
924                 /* only send messages for channels we are using */
925
926                 uint16_t mask = _playback_filter.get_channel_mask();
927
928                 for (uint8_t channel = 0; channel <= 0xF; channel++) {
929
930                         if ((1<<channel) & mask) {
931
932                                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
933                                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
934                                 write_immediate_event (3, ev);
935
936                                 /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
937                                    silence notes that came from another non-muted track. */
938                         }
939                 }
940
941                 /* Resolve active notes. */
942                 midi_diskstream()->resolve_tracker(_immediate_events, Port::port_offset());
943         }
944 }
945
946 void
947 MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd)
948 {
949         Track::monitoring_changed (self, gcd);
950
951         /* monitoring state changed, so flush out any on notes at the
952          * port level.
953          */
954
955         PortSet& ports (_output->ports());
956
957         for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
958                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
959                 if (mp) {
960                         mp->require_resolve ();
961                 }
962         }
963
964         boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
965
966         if (md) {
967                 md->reset_tracker ();
968         }
969 }
970
971 MonitorState
972 MidiTrack::monitoring_state () const
973 {
974         MonitorState ms = Track::monitoring_state();
975         if (ms == MonitoringSilence) {
976                 return MonitoringInput;
977         }
978         return ms;
979 }