Remove LocaleGuard from ARDOUR::MidiTrack class
[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
283         /* This is called after all session state has been restored but before
284            have been made ports and connections are established.
285         */
286
287         if (pending_state == 0) {
288                 return;
289         }
290
291         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
292
293                 _freeze_record.state = Frozen;
294
295                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
296                         delete *i;
297                 }
298                 _freeze_record.processor_info.clear ();
299
300                 std::string str;
301                 if (fnode->get_property (X_("playlist"), str)) {
302                         boost::shared_ptr<Playlist> pl = _session.playlists->by_name (str);
303                         if (pl) {
304                                 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
305                         } else {
306                                 _freeze_record.playlist.reset();
307                                 _freeze_record.state = NoFreeze;
308                                 return;
309                         }
310                 }
311
312                 fnode->get_property (X_("state"), _freeze_record.state);
313
314                 XMLNodeConstIterator citer;
315                 XMLNodeList clist = fnode->children();
316
317                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
318                         if ((*citer)->name() != X_("processor")) {
319                                 continue;
320                         }
321
322                         if (!(*citer)->get_property (X_("id"), str)) {
323                                 continue;
324                         }
325
326                         FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
327                                                                                    boost::shared_ptr<Processor>());
328                         frii->id = str;
329                         _freeze_record.processor_info.push_back (frii);
330                 }
331         }
332
333         if (midi_diskstream ()) {
334                 midi_diskstream()->set_block_size (_session.get_block_size ());
335         }
336
337         return;
338 }
339
340 void
341 MidiTrack::restore_controls ()
342 {
343         // TODO order events (CC before PGM to set banks)
344         for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
345                 boost::shared_ptr<MidiTrack::MidiControl> mctrl = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second);
346                 if (mctrl) {
347                         mctrl->restore_value();
348                 }
349         }
350 }
351
352 void
353 MidiTrack::update_controls(const BufferSet& bufs)
354 {
355         const MidiBuffer& buf = bufs.get_midi(0);
356         for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
357                 const Evoral::Event<framepos_t>&         ev      = *e;
358                 const Evoral::Parameter                  param   = midi_parameter(ev.buffer(), ev.size());
359                 const boost::shared_ptr<Evoral::Control> control = this->control(param);
360                 if (control) {
361                         control->set_double(ev.value(), _session.transport_frame(), false);
362                 }
363         }
364 }
365
366 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
367  *  or set to false.
368  */
369 int
370 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
371 {
372         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
373         if (!lm.locked()) {
374                 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
375                 framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
376                 if (can_internal_playback_seek(::llabs(playback_distance))) {
377                         /* TODO should declick, and/or note-off */
378                         internal_playback_seek(playback_distance);
379                 }
380                 return 0;
381         }
382
383         boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
384
385         if (n_outputs().n_total() == 0 && _processors.empty()) {
386                 return 0;
387         }
388
389         if (!_active) {
390                 silence (nframes);
391                 if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
392                         _meter->reset();
393                 }
394                 return 0;
395         }
396
397         framepos_t transport_frame = _session.transport_frame();
398
399         int dret;
400         framecnt_t playback_distance;
401
402         if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
403                 /* need to do this so that the diskstream sets its
404                    playback distance to zero, thus causing diskstream::commit
405                    to do nothing.
406                    */
407                 BufferSet bufs; /* empty set - is OK, since nothing will happen */
408
409                 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
410                 need_butler = diskstream->commit (playback_distance);
411                 return dret;
412         }
413
414         BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
415
416         fill_buffers_with_input (bufs, _input, nframes);
417
418         /* filter captured data before meter sees it */
419         _capture_filter.filter (bufs);
420
421         if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
422                 _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
423         }
424
425
426         _silent = false;
427
428         if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
429                 need_butler = diskstream->commit (playback_distance);
430                 silence (nframes);
431                 return dret;
432         }
433
434         /* note diskstream uses our filter to filter/map playback channels appropriately. */
435
436         if (monitoring_state() == MonitoringInput) {
437
438                 /* not actually recording, but we want to hear the input material anyway,
439                    at least potentially (depending on monitoring options)
440                 */
441
442                 /* because the playback buffer is event based and not a
443                  * continuous stream, we need to make sure that we empty
444                  * it of events every cycle to avoid it filling up with events
445                  * read from disk, while we are actually monitoring input
446                  */
447
448                 diskstream->flush_playback (start_frame, end_frame);
449
450         }
451
452
453         /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
454
455         write_out_of_band_data (bufs, start_frame, end_frame, nframes);
456
457         /* final argument: don't waste time with automation if we're not recording or rolling */
458
459         process_output_buffers (bufs, start_frame, end_frame, nframes,
460                                 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
461
462         flush_processor_buffers_locked (nframes);
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::Event<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.event_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         return (_immediate_events.write (0, Evoral::MIDI_EVENT, size, buf) == size);
708 }
709
710 void
711 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
712 {
713         switch (param.type()) {
714         case MidiCCAutomation:
715         case MidiPgmChangeAutomation:
716         case MidiPitchBenderAutomation:
717         case MidiChannelPressureAutomation:
718         case MidiNotePressureAutomation:
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::restore_value ()
731 {
732         actually_set_value (get_value(), Controllable::NoGroup);
733 }
734
735 void
736 MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
737 {
738         const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
739         const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
740
741         bool valid = false;
742         if (isinf_local(val)) {
743                 cerr << "MIDIControl value is infinity" << endl;
744         } else if (isnan_local(val)) {
745                 cerr << "MIDIControl value is NaN" << endl;
746         } else if (val < desc.lower) {
747                 cerr << "MIDIControl value is < " << desc.lower << endl;
748         } else if (val > desc.upper) {
749                 cerr << "MIDIControl value is > " << desc.upper << endl;
750         } else {
751                 valid = true;
752         }
753
754         if (!valid) {
755                 return;
756         }
757
758         assert(val <= desc.upper);
759         if ( ! _list || ! automation_playback()) {
760                 size_t size = 3;
761                 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
762                 switch(parameter.type()) {
763                 case MidiCCAutomation:
764                         ev[0] += MIDI_CMD_CONTROL;
765                         ev[1] = parameter.id();
766                         ev[2] = int(val);
767                         break;
768
769                 case MidiPgmChangeAutomation:
770                         size = 2;
771                         ev[0] += MIDI_CMD_PGM_CHANGE;
772                         ev[1] = int(val);
773                         break;
774
775                 case MidiChannelPressureAutomation:
776                         size = 2;
777                         ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
778                         ev[1] = int(val);
779                         break;
780
781                 case MidiNotePressureAutomation:
782                         ev[0] += MIDI_CMD_NOTE_PRESSURE;
783                         ev[1] = parameter.id();
784                         ev[2] = int(val);
785                         break;
786
787                 case MidiPitchBenderAutomation:
788                         ev[0] += MIDI_CMD_BENDER;
789                         ev[1] = 0x7F & int(val);
790                         ev[2] = 0x7F & (int(val) >> 7);
791                         break;
792
793                 default:
794                         assert(false);
795                 }
796                 _route->write_immediate_event(size,  ev);
797         }
798
799         AutomationControl::actually_set_value(val, group_override);
800 }
801
802 void
803 MidiTrack::set_step_editing (bool yn)
804 {
805         if (_session.record_status() != Session::Disabled) {
806                 return;
807         }
808
809         if (yn != _step_editing) {
810                 _step_editing = yn;
811                 StepEditStatusChange (yn);
812         }
813 }
814
815 boost::shared_ptr<SMFSource>
816 MidiTrack::write_source (uint32_t)
817 {
818         return midi_diskstream()->write_source ();
819 }
820
821 void
822 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
823 {
824         if (_playback_filter.set_channel_mode(mode, mask)) {
825                 _session.set_dirty();
826         }
827 }
828
829 void
830 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
831 {
832         if (_capture_filter.set_channel_mode(mode, mask)) {
833                 _session.set_dirty();
834         }
835 }
836
837 void
838 MidiTrack::set_playback_channel_mask (uint16_t mask)
839 {
840         if (_playback_filter.set_channel_mask(mask)) {
841                 _session.set_dirty();
842         }
843 }
844
845 void
846 MidiTrack::set_capture_channel_mask (uint16_t mask)
847 {
848         if (_capture_filter.set_channel_mask(mask)) {
849                 _session.set_dirty();
850         }
851 }
852
853 boost::shared_ptr<MidiPlaylist>
854 MidiTrack::midi_playlist ()
855 {
856         return midi_diskstream()->midi_playlist ();
857 }
858
859 void
860 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
861 {
862         DataRecorded (src); /* EMIT SIGNAL */
863 }
864
865 bool
866 MidiTrack::input_active () const
867 {
868         return _input_active;
869 }
870
871 void
872 MidiTrack::set_input_active (bool yn)
873 {
874         if (yn != _input_active) {
875                 _input_active = yn;
876                 map_input_active (yn);
877                 InputActiveChanged (); /* EMIT SIGNAL */
878         }
879 }
880
881 void
882 MidiTrack::map_input_active (bool yn)
883 {
884         if (!_input) {
885                 return;
886         }
887
888         PortSet& ports (_input->ports());
889
890         for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
891                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
892                 if (yn != mp->input_active()) {
893                         mp->set_input_active (yn);
894                 }
895         }
896 }
897
898 void
899 MidiTrack::track_input_active (IOChange change, void* /* src */)
900 {
901         if (change.type & IOChange::ConfigurationChanged) {
902                 map_input_active (_input_active);
903         }
904 }
905
906 boost::shared_ptr<Diskstream>
907 MidiTrack::diskstream_factory (XMLNode const & node)
908 {
909         return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
910 }
911
912 boost::shared_ptr<MidiBuffer>
913 MidiTrack::get_gui_feed_buffer () const
914 {
915         return midi_diskstream()->get_gui_feed_buffer ();
916 }
917
918 void
919 MidiTrack::act_on_mute ()
920 {
921         /* this is called right after our mute status has changed.
922            if we are now muted, send suitable output to shutdown
923            all our notes.
924
925            XXX we should should also stop all relevant note trackers.
926         */
927
928         /* If we haven't got a diskstream yet, there's nothing to worry about,
929            and we can't call get_channel_mask() anyway.
930         */
931         if (!midi_diskstream()) {
932                 return;
933         }
934
935         if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) {
936                 /* only send messages for channels we are using */
937
938                 uint16_t mask = _playback_filter.get_channel_mask();
939
940                 for (uint8_t channel = 0; channel <= 0xF; channel++) {
941
942                         if ((1<<channel) & mask) {
943
944                                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
945                                 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
946                                 write_immediate_event (3, ev);
947
948                                 /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
949                                    silence notes that came from another non-muted track. */
950                         }
951                 }
952
953                 /* Resolve active notes. */
954                 midi_diskstream()->resolve_tracker(_immediate_events, Port::port_offset());
955         }
956 }
957
958 void
959 MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd)
960 {
961         Track::monitoring_changed (self, gcd);
962
963         /* monitoring state changed, so flush out any on notes at the
964          * port level.
965          */
966
967         PortSet& ports (_output->ports());
968
969         for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
970                 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
971                 if (mp) {
972                         mp->require_resolve ();
973                 }
974         }
975
976         boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
977
978         if (md) {
979                 md->reset_tracker ();
980         }
981 }
982
983 MonitorState
984 MidiTrack::monitoring_state () const
985 {
986         MonitorState ms = Track::monitoring_state();
987         if (ms == MonitoringSilence) {
988                 return MonitoringInput;
989         }
990         return ms;
991 }