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
32 #include "pbd/enumwriter.h"
33 #include "pbd/convert.h"
34 #include "evoral/midi_util.h"
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"
57 class InterThreadInfo;
64 using namespace ARDOUR;
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)
77 MidiTrack::~MidiTrack ()
88 _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
93 boost::shared_ptr<Diskstream>
94 MidiTrack::create_diskstream ()
96 MidiDiskstream::Flag dflags = MidiDiskstream::Flag (MidiDiskstream::Recordable);
98 assert(_mode != Destructive);
100 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
105 MidiTrack::set_record_enabled (bool yn, void *src)
111 Track::set_record_enabled (yn, src);
115 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
117 /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
118 and the diskstream must be set up to fill its buffers using the correct _note_mode.
120 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
121 mds->set_note_mode (_note_mode);
123 Track::set_diskstream (ds);
125 mds->reset_tracker ();
127 _diskstream->set_track (this);
128 _diskstream->set_destructive (_mode == Destructive);
129 _diskstream->set_record_enabled (false);
131 _diskstream_data_recorded_connection.disconnect ();
132 mds->DataRecorded.connect_same_thread (
133 _diskstream_data_recorded_connection,
134 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
136 DiskstreamChanged (); /* EMIT SIGNAL */
139 boost::shared_ptr<MidiDiskstream>
140 MidiTrack::midi_diskstream() const
142 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
146 MidiTrack::set_state (const XMLNode& node, int version)
148 const XMLProperty *prop;
150 /* This must happen before Track::set_state(), as there will be a buffer
151 fill during that call, and we must fill buffers using the correct
154 if ((prop = node.property (X_("note-mode"))) != 0) {
155 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
157 _note_mode = Sustained;
160 if (Track::set_state (node, version)) {
164 // No destructive MIDI tracks (yet?)
167 if ((prop = node.property ("input-active")) != 0) {
168 set_input_active (string_is_affirmative (prop->value()));
171 ChannelMode playback_channel_mode = AllChannels;
172 ChannelMode capture_channel_mode = AllChannels;
174 if ((prop = node.property ("playback-channel-mode")) != 0) {
175 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
177 if ((prop = node.property ("capture-channel-mode")) != 0) {
178 capture_channel_mode = ChannelMode (string_2_enum(prop->value(), capture_channel_mode));
180 if ((prop = node.property ("channel-mode")) != 0) {
181 /* 3.0 behaviour where capture and playback modes were not separated */
182 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
183 capture_channel_mode = playback_channel_mode;
186 unsigned int playback_channel_mask = 0xffff;
187 unsigned int capture_channel_mask = 0xffff;
189 if ((prop = node.property ("playback-channel-mask")) != 0) {
190 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
192 if ((prop = node.property ("capture-channel-mask")) != 0) {
193 sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
195 if ((prop = node.property ("channel-mask")) != 0) {
196 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
197 capture_channel_mask = playback_channel_mask;
200 set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
201 set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
203 pending_state = const_cast<XMLNode*> (&node);
205 if (_session.state_of_the_state() & Session::Loading) {
206 _session.StateReady.connect_same_thread (
207 *this, boost::bind (&MidiTrack::set_state_part_two, this));
209 set_state_part_two ();
216 MidiTrack::state(bool full_state)
218 XMLNode& root (Track::state(full_state));
219 XMLNode* freeze_node;
222 if (_freeze_record.playlist) {
225 freeze_node = new XMLNode (X_("freeze-info"));
226 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
227 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
229 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
230 inode = new XMLNode (X_("processor"));
231 (*i)->id.print (buf, sizeof(buf));
232 inode->add_property (X_("id"), buf);
233 inode->add_child_copy ((*i)->state);
235 freeze_node->add_child_nocopy (*inode);
238 root.add_child_nocopy (*freeze_node);
241 root.add_property("playback_channel-mode", enum_2_string(get_playback_channel_mode()));
242 root.add_property("capture_channel-mode", enum_2_string(get_capture_channel_mode()));
243 snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
244 root.add_property("playback-channel-mask", buf);
245 snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
246 root.add_property("capture-channel-mask", buf);
248 root.add_property ("note-mode", enum_2_string (_note_mode));
249 root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
250 root.add_property ("input-active", (_input_active ? "yes" : "no"));
256 MidiTrack::set_state_part_two ()
260 LocaleGuard lg (X_("C"));
262 /* This is called after all session state has been restored but before
263 have been made ports and connections are established.
266 if (pending_state == 0) {
270 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
272 _freeze_record.state = Frozen;
274 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
277 _freeze_record.processor_info.clear ();
279 if ((prop = fnode->property (X_("playlist"))) != 0) {
280 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
282 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
284 _freeze_record.playlist.reset();
285 _freeze_record.state = NoFreeze;
290 if ((prop = fnode->property (X_("state"))) != 0) {
291 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
294 XMLNodeConstIterator citer;
295 XMLNodeList clist = fnode->children();
297 for (citer = clist.begin(); citer != clist.end(); ++citer) {
298 if ((*citer)->name() != X_("processor")) {
302 if ((prop = (*citer)->property (X_("id"))) == 0) {
306 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
307 boost::shared_ptr<Processor>());
308 frii->id = prop->value ();
309 _freeze_record.processor_info.push_back (frii);
313 if (midi_diskstream ()) {
314 midi_diskstream()->set_block_size (_session.get_block_size ());
321 MidiTrack::update_controls(const BufferSet& bufs)
323 const MidiBuffer& buf = bufs.get_midi(0);
324 for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
325 const Evoral::MIDIEvent<framepos_t>& ev = *e;
326 const Evoral::Parameter param = midi_parameter(ev.buffer(), ev.size());
327 const boost::shared_ptr<Evoral::Control> control = this->control(param);
329 control->set_double(ev.value(), _session.transport_frame(), false);
334 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
338 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
340 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
342 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
343 framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
344 if (can_internal_playback_seek(llabs(playback_distance))) {
345 /* TODO should declick, and/or note-off */
346 internal_playback_seek(playback_distance);
351 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
353 if (n_outputs().n_total() == 0 && _processors.empty()) {
359 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
365 framepos_t transport_frame = _session.transport_frame();
368 framecnt_t playback_distance;
370 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
371 /* need to do this so that the diskstream sets its
372 playback distance to zero, thus causing diskstream::commit
375 BufferSet bufs; /* empty set - is OK, since nothing will happen */
377 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
378 need_butler = diskstream->commit (playback_distance);
382 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
384 fill_buffers_with_input (bufs, _input, nframes);
386 /* filter captured data before meter sees it */
387 _capture_filter.filter (bufs);
389 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
390 _meter->run (bufs, start_frame, end_frame, nframes, true);
396 if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
397 need_butler = diskstream->commit (playback_distance);
402 /* note diskstream uses our filter to filter/map playback channels appropriately. */
404 if (monitoring_state() == MonitoringInput) {
406 /* not actually recording, but we want to hear the input material anyway,
407 at least potentially (depending on monitoring options)
410 /* because the playback buffer is event based and not a
411 * continuous stream, we need to make sure that we empty
412 * it of events every cycle to avoid it filling up with events
413 * read from disk, while we are actually monitoring input
416 diskstream->flush_playback (start_frame, end_frame);
421 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
423 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
425 /* final argument: don't waste time with automation if we're not recording or rolling */
427 process_output_buffers (bufs, start_frame, end_frame, nframes,
428 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
430 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
431 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
433 d->flush_buffers (nframes);
437 need_butler = diskstream->commit (playback_distance);
443 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
445 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
447 if (ret == 0 && _step_editing) {
448 push_midi_input_to_step_edit_ringbuffer (nframes);
455 MidiTrack::realtime_locate ()
457 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
463 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
464 (*i)->realtime_locate ();
467 midi_diskstream()->reset_tracker ();
471 MidiTrack::realtime_handle_transport_stopped ()
473 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
479 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
480 (*i)->realtime_handle_transport_stopped ();
485 MidiTrack::non_realtime_locate (framepos_t pos)
487 Track::non_realtime_locate(pos);
489 boost::shared_ptr<MidiPlaylist> playlist = midi_diskstream()->midi_playlist();
494 /* Get the top unmuted region at this position. */
495 boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(
496 playlist->top_unmuted_region_at(pos));
501 Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK);
506 /* Update track controllers based on its "automation". */
507 const framepos_t origin = region->position() - region->start();
508 BeatsFramesConverter bfc(_session.tempo_map(), origin);
509 for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
510 boost::shared_ptr<MidiTrack::MidiControl> tcontrol;
511 boost::shared_ptr<Evoral::Control> rcontrol;
512 if ((tcontrol = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) &&
513 (rcontrol = region->control(tcontrol->parameter()))) {
514 const Evoral::Beats pos_beats = bfc.from(pos - origin);
515 tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()));
521 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
523 PortSet& ports (_input->ports());
525 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
527 Buffer& b (p->get_buffer (nframes));
528 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
531 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
533 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
535 /* note on, since for step edit, note length is determined
539 if (ev.is_note_on()) {
540 /* we don't care about the time for this purpose */
541 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
548 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
550 MidiBuffer& buf (bufs.get_midi (0));
552 update_controls (bufs);
554 // Append immediate events
556 if (_immediate_events.read_space()) {
558 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
559 name(), _immediate_events.read_space()));
561 /* write as many of the immediate events as we can, but give "true" as
562 * the last argument ("stop on overflow in destination") so that we'll
563 * ship the rest out next time.
565 * the Port::port_offset() + (nframes-1) argument puts all these events at the last
566 * possible position of the output buffer, so that we do not
567 * violate monotonicity when writing. Port::port_offset() will
568 * be non-zero if we're in a split process cycle.
570 _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
575 MidiTrack::export_stuff (BufferSet& buffers,
578 boost::shared_ptr<Processor> endpoint,
579 bool include_endpoint,
583 if (buffers.count().n_midi() == 0) {
587 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
589 Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
591 boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist>(diskstream->playlist());
596 buffers.get_midi(0).clear();
597 if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) {
601 //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
606 boost::shared_ptr<Region>
607 MidiTrack::bounce (InterThreadInfo& itt)
609 return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false);
612 boost::shared_ptr<Region>
613 MidiTrack::bounce_range (framepos_t start,
615 InterThreadInfo& itt,
616 boost::shared_ptr<Processor> endpoint,
617 bool include_endpoint)
619 vector<boost::shared_ptr<Source> > srcs;
620 return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
624 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
626 std::cerr << "MIDI freeze currently unsupported" << std::endl;
630 MidiTrack::unfreeze ()
632 _freeze_record.state = UnFrozen;
633 FreezeChange (); /* EMIT SIGNAL */
637 MidiTrack::set_note_mode (NoteMode m)
640 midi_diskstream()->set_note_mode(m);
644 MidiTrack::describe_parameter (Evoral::Parameter param)
646 const std::string str(instrument_info().get_controller_name(param));
647 return str.empty() ? Automatable::describe_parameter(param) : str;
651 MidiTrack::midi_panic()
653 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
654 for (uint8_t channel = 0; channel <= 0xF; channel++) {
655 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
656 write_immediate_event(3, ev);
657 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
658 write_immediate_event(3, ev);
659 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
660 write_immediate_event(3, ev);
664 /** \return true on success, false on failure (no buffer space left)
667 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
669 if (!Evoral::midi_event_is_valid(buf, size)) {
670 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
673 const uint32_t type = midi_parameter_type(buf[0]);
674 return (_immediate_events.write (0, type, size, buf) == size);
678 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
680 switch (param.type()) {
681 case MidiCCAutomation:
682 case MidiPgmChangeAutomation:
683 case MidiPitchBenderAutomation:
684 case MidiChannelPressureAutomation:
685 case MidiSystemExclusiveAutomation:
686 /* The track control for MIDI parameters is for immediate events to act
687 as a control surface, write/touch for them is not currently
691 Automatable::set_parameter_automation_state(param, state);
696 MidiTrack::MidiControl::set_value(double val)
698 const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
699 const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
702 if (isinf_local(val)) {
703 cerr << "MIDIControl value is infinity" << endl;
704 } else if (isnan_local(val)) {
705 cerr << "MIDIControl value is NaN" << endl;
706 } else if (val < desc.lower) {
707 cerr << "MIDIControl value is < " << desc.lower << endl;
708 } else if (val > desc.upper) {
709 cerr << "MIDIControl value is > " << desc.upper << endl;
718 assert(val <= desc.upper);
719 if ( ! _list || ! automation_playback()) {
721 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
722 switch(parameter.type()) {
723 case MidiCCAutomation:
724 ev[0] += MIDI_CMD_CONTROL;
725 ev[1] = parameter.id();
729 case MidiPgmChangeAutomation:
731 ev[0] += MIDI_CMD_PGM_CHANGE;
735 case MidiChannelPressureAutomation:
737 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
741 case MidiPitchBenderAutomation:
742 ev[0] += MIDI_CMD_BENDER;
743 ev[1] = 0x7F & int(val);
744 ev[2] = 0x7F & (int(val) >> 7);
750 _route->write_immediate_event(size, ev);
753 AutomationControl::set_value(val);
757 MidiTrack::set_step_editing (bool yn)
759 if (_session.record_status() != Session::Disabled) {
763 if (yn != _step_editing) {
765 StepEditStatusChange (yn);
769 boost::shared_ptr<SMFSource>
770 MidiTrack::write_source (uint32_t)
772 return midi_diskstream()->write_source ();
776 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
778 if (_playback_filter.set_channel_mode(mode, mask)) {
779 _session.set_dirty();
784 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
786 if (_capture_filter.set_channel_mode(mode, mask)) {
787 _session.set_dirty();
792 MidiTrack::set_playback_channel_mask (uint16_t mask)
794 if (_playback_filter.set_channel_mask(mask)) {
795 _session.set_dirty();
800 MidiTrack::set_capture_channel_mask (uint16_t mask)
802 if (_capture_filter.set_channel_mask(mask)) {
803 _session.set_dirty();
807 boost::shared_ptr<MidiPlaylist>
808 MidiTrack::midi_playlist ()
810 return midi_diskstream()->midi_playlist ();
814 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
816 DataRecorded (src); /* EMIT SIGNAL */
820 MidiTrack::input_active () const
822 return _input_active;
826 MidiTrack::set_input_active (bool yn)
828 if (yn != _input_active) {
830 map_input_active (yn);
831 InputActiveChanged (); /* EMIT SIGNAL */
836 MidiTrack::map_input_active (bool yn)
842 PortSet& ports (_input->ports());
844 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
845 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
846 if (yn != mp->input_active()) {
847 mp->set_input_active (yn);
853 MidiTrack::track_input_active (IOChange change, void* /* src */)
855 if (change.type & IOChange::ConfigurationChanged) {
856 map_input_active (_input_active);
860 boost::shared_ptr<Diskstream>
861 MidiTrack::diskstream_factory (XMLNode const & node)
863 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
866 boost::shared_ptr<MidiBuffer>
867 MidiTrack::get_gui_feed_buffer () const
869 return midi_diskstream()->get_gui_feed_buffer ();
873 MidiTrack::act_on_mute ()
875 /* this is called right after our mute status has changed.
876 if we are now muted, send suitable output to shutdown
879 XXX we should should also stop all relevant note trackers.
882 /* If we haven't got a diskstream yet, there's nothing to worry about,
883 and we can't call get_channel_mask() anyway.
885 if (!midi_diskstream()) {
889 if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) {
890 /* only send messages for channels we are using */
892 uint16_t mask = _playback_filter.get_channel_mask();
894 for (uint8_t channel = 0; channel <= 0xF; channel++) {
896 if ((1<<channel) & mask) {
898 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
899 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
900 write_immediate_event (3, ev);
902 /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
903 silence notes that came from another non-muted track. */
907 /* Resolve active notes. */
908 midi_diskstream()->resolve_tracker(_immediate_events, 0);
913 MidiTrack::set_monitoring (MonitorChoice mc)
915 if (mc != _monitoring) {
917 Track::set_monitoring (mc);
919 /* monitoring state changed, so flush out any on notes at the
923 PortSet& ports (_output->ports());
925 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
926 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
928 mp->require_resolve ();
932 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
935 md->reset_tracker ();
941 MidiTrack::monitoring_state () const
943 MonitorState ms = Track::monitoring_state();
944 if (ms == MonitoringSilence) {
945 return MonitoringInput;