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