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