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