2 Copyright (C) 2006 Paul Davis
3 Author: David Robillard
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.
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.
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.
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)
28 #define isinf_local std::isinf
29 #define isnan_local std::isnan
33 #include "pbd/enumwriter.h"
34 #include "pbd/convert.h"
35 #include "evoral/midi_util.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_track.h"
46 #include "ardour/parameter_types.h"
47 #include "ardour/port.h"
48 #include "ardour/processor.h"
49 #include "ardour/session.h"
50 #include "ardour/session_playlists.h"
51 #include "ardour/utils.h"
56 class InterThreadInfo;
63 using namespace ARDOUR;
66 MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
67 : Track (sess, name, flag, mode, DataType::MIDI)
68 , _immediate_events(1024) // FIXME: size?
69 , _step_edit_ring_buffer(64) // FIXME: size?
70 , _note_mode(Sustained)
71 , _step_editing (false)
72 , _input_active (true)
73 , _playback_channel_mask(0x0000ffff)
74 , _capture_channel_mask(0x0000ffff)
78 MidiTrack::~MidiTrack ()
89 _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
94 boost::shared_ptr<Diskstream>
95 MidiTrack::create_diskstream ()
97 MidiDiskstream::Flag dflags = MidiDiskstream::Flag (MidiDiskstream::Recordable);
99 assert(_mode != Destructive);
101 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
106 MidiTrack::set_record_enabled (bool yn, void *src)
112 Track::set_record_enabled (yn, src);
116 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
118 /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
119 and the diskstream must be set up to fill its buffers using the correct _note_mode.
121 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
122 mds->set_note_mode (_note_mode);
124 Track::set_diskstream (ds);
126 mds->reset_tracker ();
128 _diskstream->set_track (this);
129 _diskstream->set_destructive (_mode == Destructive);
130 _diskstream->set_record_enabled (false);
132 _diskstream_data_recorded_connection.disconnect ();
133 mds->DataRecorded.connect_same_thread (
134 _diskstream_data_recorded_connection,
135 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
137 DiskstreamChanged (); /* EMIT SIGNAL */
140 boost::shared_ptr<MidiDiskstream>
141 MidiTrack::midi_diskstream() const
143 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
147 MidiTrack::set_state (const XMLNode& node, int version)
149 const XMLProperty *prop;
151 /* This must happen before Track::set_state(), as there will be a buffer
152 fill during that call, and we must fill buffers using the correct
155 if ((prop = node.property (X_("note-mode"))) != 0) {
156 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
158 _note_mode = Sustained;
161 if (Track::set_state (node, version)) {
165 // No destructive MIDI tracks (yet?)
168 if ((prop = node.property ("input-active")) != 0) {
169 set_input_active (string_is_affirmative (prop->value()));
172 ChannelMode playback_channel_mode = AllChannels;
173 ChannelMode capture_channel_mode = AllChannels;
175 if ((prop = node.property ("playback-channel-mode")) != 0) {
176 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
178 if ((prop = node.property ("capture-channel-mode")) != 0) {
179 capture_channel_mode = ChannelMode (string_2_enum(prop->value(), capture_channel_mode));
181 if ((prop = node.property ("channel-mode")) != 0) {
182 /* 3.0 behaviour where capture and playback modes were not separated */
183 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
184 capture_channel_mode = playback_channel_mode;
187 unsigned int playback_channel_mask = 0xffff;
188 unsigned int capture_channel_mask = 0xffff;
190 if ((prop = node.property ("playback-channel-mask")) != 0) {
191 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
193 if ((prop = node.property ("capture-channel-mask")) != 0) {
194 sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
196 if ((prop = node.property ("channel-mask")) != 0) {
197 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
198 capture_channel_mask = playback_channel_mask;
201 set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
202 set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
204 pending_state = const_cast<XMLNode*> (&node);
206 if (_session.state_of_the_state() & Session::Loading) {
207 _session.StateReady.connect_same_thread (
208 *this, boost::bind (&MidiTrack::set_state_part_two, this));
210 set_state_part_two ();
217 MidiTrack::state(bool full_state)
219 XMLNode& root (Track::state(full_state));
220 XMLNode* freeze_node;
223 if (_freeze_record.playlist) {
226 freeze_node = new XMLNode (X_("freeze-info"));
227 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
228 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
230 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
231 inode = new XMLNode (X_("processor"));
232 (*i)->id.print (buf, sizeof(buf));
233 inode->add_property (X_("id"), buf);
234 inode->add_child_copy ((*i)->state);
236 freeze_node->add_child_nocopy (*inode);
239 root.add_child_nocopy (*freeze_node);
242 root.add_property("playback_channel-mode", enum_2_string(get_playback_channel_mode()));
243 root.add_property("capture_channel-mode", enum_2_string(get_capture_channel_mode()));
244 snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
245 root.add_property("playback-channel-mask", buf);
246 snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
247 root.add_property("capture-channel-mask", buf);
249 root.add_property ("note-mode", enum_2_string (_note_mode));
250 root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
251 root.add_property ("input-active", (_input_active ? "yes" : "no"));
257 MidiTrack::set_state_part_two ()
261 LocaleGuard lg (X_("C"));
263 /* This is called after all session state has been restored but before
264 have been made ports and connections are established.
267 if (pending_state == 0) {
271 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
273 _freeze_record.state = Frozen;
275 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
278 _freeze_record.processor_info.clear ();
280 if ((prop = fnode->property (X_("playlist"))) != 0) {
281 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
283 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
285 _freeze_record.playlist.reset();
286 _freeze_record.state = NoFreeze;
291 if ((prop = fnode->property (X_("state"))) != 0) {
292 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
295 XMLNodeConstIterator citer;
296 XMLNodeList clist = fnode->children();
298 for (citer = clist.begin(); citer != clist.end(); ++citer) {
299 if ((*citer)->name() != X_("processor")) {
303 if ((prop = (*citer)->property (X_("id"))) == 0) {
307 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
308 boost::shared_ptr<Processor>());
309 frii->id = prop->value ();
310 _freeze_record.processor_info.push_back (frii);
314 if (midi_diskstream ()) {
315 midi_diskstream()->set_block_size (_session.get_block_size ());
321 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
325 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
327 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
329 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
330 framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
331 if (can_internal_playback_seek(llabs(playback_distance))) {
332 /* TODO should declick, and/or note-off */
333 internal_playback_seek(playback_distance);
338 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
340 if (n_outputs().n_total() == 0 && _processors.empty()) {
346 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
352 framepos_t transport_frame = _session.transport_frame();
355 framecnt_t playback_distance;
357 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
358 /* need to do this so that the diskstream sets its
359 playback distance to zero, thus causing diskstream::commit
362 BufferSet bufs; /* empty set - is OK, since nothing will happen */
364 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
365 need_butler = diskstream->commit (playback_distance);
369 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
371 fill_buffers_with_input (bufs, _input, nframes);
373 /* filter captured data before meter sees it */
374 filter_channels (bufs, get_capture_channel_mode(), get_capture_channel_mask());
376 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
377 _meter->run (bufs, start_frame, end_frame, nframes, true);
383 if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
384 need_butler = diskstream->commit (playback_distance);
389 /* filter playback data before we do anything else */
391 filter_channels (bufs, get_playback_channel_mode(), get_playback_channel_mask ());
393 if (monitoring_state() == MonitoringInput) {
395 /* not actually recording, but we want to hear the input material anyway,
396 at least potentially (depending on monitoring options)
399 /* because the playback buffer is event based and not a
400 * continuous stream, we need to make sure that we empty
401 * it of events every cycle to avoid it filling up with events
402 * read from disk, while we are actually monitoring input
405 diskstream->flush_playback (start_frame, end_frame);
410 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
412 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
414 /* final argument: don't waste time with automation if we're not recording or rolling */
416 process_output_buffers (bufs, start_frame, end_frame, nframes,
417 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
419 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
420 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
422 d->flush_buffers (nframes);
426 need_butler = diskstream->commit (playback_distance);
432 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
434 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
436 if (ret == 0 && _step_editing) {
437 push_midi_input_to_step_edit_ringbuffer (nframes);
444 MidiTrack::realtime_locate ()
446 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
452 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
453 (*i)->realtime_locate ();
456 midi_diskstream()->reset_tracker ();
460 MidiTrack::realtime_handle_transport_stopped ()
462 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
468 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
469 (*i)->realtime_handle_transport_stopped ();
474 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
476 PortSet& ports (_input->ports());
478 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
480 Buffer& b (p->get_buffer (nframes));
481 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
484 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
486 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
488 /* note on, since for step edit, note length is determined
492 if (ev.is_note_on()) {
493 /* we don't care about the time for this purpose */
494 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
501 MidiTrack::filter_channels (BufferSet& bufs, ChannelMode mode, uint32_t mask)
503 if (mode == AllChannels) {
507 MidiBuffer& buf (bufs.get_midi (0));
509 for (MidiBuffer::iterator e = buf.begin(); e != buf.end(); ) {
511 Evoral::MIDIEvent<framepos_t> ev(*e, false);
513 if (ev.is_channel_event()) {
516 if (0 == ((1<<ev.channel()) & mask)) {
523 ev.set_channel (PBD::ffs (mask) - 1);
527 /* handled by the opening if() */
538 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
540 MidiBuffer& buf (bufs.get_midi (0));
542 // Append immediate events
544 if (_immediate_events.read_space()) {
546 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
547 name(), _immediate_events.read_space()));
549 /* write as many of the immediate events as we can, but give "true" as
550 * the last argument ("stop on overflow in destination") so that we'll
551 * ship the rest out next time.
553 * the Port::port_offset() + (nframes-1) argument puts all these events at the last
554 * possible position of the output buffer, so that we do not
555 * violate monotonicity when writing. Port::port_offset() will
556 * be non-zero if we're in a split process cycle.
558 _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
563 MidiTrack::export_stuff (BufferSet& buffers,
566 boost::shared_ptr<Processor> endpoint,
567 bool include_endpoint,
571 if (buffers.count().n_midi() == 0) {
575 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
577 Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
579 boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist>(diskstream->playlist());
584 buffers.get_midi(0).clear();
585 if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) {
589 //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
594 boost::shared_ptr<Region>
595 MidiTrack::bounce (InterThreadInfo& itt)
597 return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false);
600 boost::shared_ptr<Region>
601 MidiTrack::bounce_range (framepos_t start,
603 InterThreadInfo& itt,
604 boost::shared_ptr<Processor> endpoint,
605 bool include_endpoint)
607 vector<boost::shared_ptr<Source> > srcs;
608 return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
612 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
614 std::cerr << "MIDI freeze currently unsupported" << std::endl;
618 MidiTrack::unfreeze ()
620 _freeze_record.state = UnFrozen;
621 FreezeChange (); /* EMIT SIGNAL */
625 MidiTrack::set_note_mode (NoteMode m)
628 midi_diskstream()->set_note_mode(m);
632 MidiTrack::describe_parameter (Evoral::Parameter param)
634 const std::string str(instrument_info().get_controller_name(param));
635 return str.empty() ? Automatable::describe_parameter(param) : str;
639 MidiTrack::midi_panic()
641 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
642 for (uint8_t channel = 0; channel <= 0xF; channel++) {
643 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
644 write_immediate_event(3, ev);
645 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
646 write_immediate_event(3, ev);
647 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
648 write_immediate_event(3, ev);
652 /** \return true on success, false on failure (no buffer space left)
655 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
657 if (!Evoral::midi_event_is_valid(buf, size)) {
658 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
661 const uint32_t type = midi_parameter_type(buf[0]);
662 return (_immediate_events.write (0, type, size, buf) == size);
666 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
668 switch (param.type()) {
669 case MidiCCAutomation:
670 case MidiPgmChangeAutomation:
671 case MidiPitchBenderAutomation:
672 case MidiChannelPressureAutomation:
673 case MidiSystemExclusiveAutomation:
674 /* The track control for MIDI parameters is for immediate events to act
675 as a control surface, write/touch for them is not currently
679 Automatable::set_parameter_automation_state(param, state);
684 MidiTrack::MidiControl::set_value(double val)
686 const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
687 const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
690 if (isinf_local(val)) {
691 cerr << "MIDIControl value is infinity" << endl;
692 } else if (isnan_local(val)) {
693 cerr << "MIDIControl value is NaN" << endl;
694 } else if (val < desc.lower) {
695 cerr << "MIDIControl value is < " << desc.lower << endl;
696 } else if (val > desc.upper) {
697 cerr << "MIDIControl value is > " << desc.upper << endl;
706 assert(val <= desc.upper);
707 if ( ! _list || ! automation_playback()) {
709 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
710 switch(parameter.type()) {
711 case MidiCCAutomation:
712 ev[0] += MIDI_CMD_CONTROL;
713 ev[1] = parameter.id();
717 case MidiPgmChangeAutomation:
719 ev[0] += MIDI_CMD_PGM_CHANGE;
723 case MidiChannelPressureAutomation:
725 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
729 case MidiPitchBenderAutomation:
730 ev[0] += MIDI_CMD_BENDER;
731 ev[1] = 0x7F & int(val);
732 ev[2] = 0x7F & (int(val) >> 7);
738 _route->write_immediate_event(size, ev);
741 AutomationControl::set_value(val);
745 MidiTrack::set_step_editing (bool yn)
747 if (_session.record_status() != Session::Disabled) {
751 if (yn != _step_editing) {
753 StepEditStatusChange (yn);
757 boost::shared_ptr<SMFSource>
758 MidiTrack::write_source (uint32_t)
760 return midi_diskstream()->write_source ();
764 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
766 ChannelMode old = get_playback_channel_mode ();
767 uint16_t old_mask = get_playback_channel_mask ();
769 if (old != mode || mask != old_mask) {
770 _set_playback_channel_mode (mode, mask);
771 PlaybackChannelModeChanged ();
772 _session.set_dirty ();
777 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
779 ChannelMode old = get_capture_channel_mode ();
780 uint16_t old_mask = get_capture_channel_mask ();
782 if (old != mode || mask != old_mask) {
783 _set_capture_channel_mode (mode, mask);
784 CaptureChannelModeChanged ();
785 _session.set_dirty ();
790 MidiTrack::set_playback_channel_mask (uint16_t mask)
792 uint16_t old = get_playback_channel_mask();
795 _set_playback_channel_mask (mask);
796 PlaybackChannelMaskChanged ();
797 _session.set_dirty ();
802 MidiTrack::set_capture_channel_mask (uint16_t mask)
804 uint16_t old = get_capture_channel_mask();
807 _set_capture_channel_mask (mask);
808 CaptureChannelMaskChanged ();
809 _session.set_dirty ();
813 boost::shared_ptr<MidiPlaylist>
814 MidiTrack::midi_playlist ()
816 return midi_diskstream()->midi_playlist ();
820 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
822 DataRecorded (src); /* EMIT SIGNAL */
826 MidiTrack::input_active () const
828 return _input_active;
832 MidiTrack::set_input_active (bool yn)
834 if (yn != _input_active) {
836 map_input_active (yn);
837 InputActiveChanged (); /* EMIT SIGNAL */
842 MidiTrack::map_input_active (bool yn)
848 PortSet& ports (_input->ports());
850 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
851 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
852 if (yn != mp->input_active()) {
853 mp->set_input_active (yn);
859 MidiTrack::track_input_active (IOChange change, void* /* src */)
861 if (change.type & IOChange::ConfigurationChanged) {
862 map_input_active (_input_active);
866 boost::shared_ptr<Diskstream>
867 MidiTrack::diskstream_factory (XMLNode const & node)
869 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
872 boost::shared_ptr<MidiBuffer>
873 MidiTrack::get_gui_feed_buffer () const
875 return midi_diskstream()->get_gui_feed_buffer ();
879 MidiTrack::act_on_mute ()
881 /* this is called right after our mute status has changed.
882 if we are now muted, send suitable output to shutdown
885 XXX we should should also stop all relevant note trackers.
888 /* If we haven't got a diskstream yet, there's nothing to worry about,
889 and we can't call get_channel_mask() anyway.
891 if (!midi_diskstream()) {
896 /* only send messages for channels we are using */
898 uint16_t mask = get_playback_channel_mask();
900 for (uint8_t channel = 0; channel <= 0xF; channel++) {
902 if ((1<<channel) & mask) {
904 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
905 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
906 write_immediate_event (3, ev);
907 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
908 write_immediate_event (3, ev);
915 MidiTrack::set_monitoring (MonitorChoice mc)
917 if (mc != _monitoring) {
919 Track::set_monitoring (mc);
921 /* monitoring state changed, so flush out any on notes at the
925 PortSet& ports (_output->ports());
927 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
928 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
930 mp->require_resolve ();
934 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
937 md->reset_tracker ();
943 MidiTrack::monitoring_state () const
945 MonitorState ms = Track::monitoring_state();
946 if (ms == MonitoringSilence) {
947 return MonitoringInput;