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/types_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/monitor_control.h"
48 #include "ardour/parameter_types.h"
49 #include "ardour/port.h"
50 #include "ardour/processor.h"
51 #include "ardour/profile.h"
52 #include "ardour/route_group_specialized.h"
53 #include "ardour/session.h"
54 #include "ardour/session_playlists.h"
55 #include "ardour/types_convert.h"
56 #include "ardour/utils.h"
61 class InterThreadInfo;
68 using namespace ARDOUR;
71 MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
72 : Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
73 , _immediate_events(6096) // FIXME: size?
74 , _step_edit_ring_buffer(64) // FIXME: size?
75 , _note_mode(Sustained)
76 , _step_editing (false)
77 , _input_active (true)
79 _session.SessionLoaded.connect_same_thread (*this, boost::bind (&MidiTrack::restore_controls, this));
82 MidiTrack::~MidiTrack ()
93 _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
98 boost::shared_ptr<Diskstream>
99 MidiTrack::create_diskstream ()
101 MidiDiskstream::Flag dflags = MidiDiskstream::Flag (MidiDiskstream::Recordable);
103 assert(_mode != Destructive);
105 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
110 MidiTrack::can_be_record_safe ()
116 return Track::can_be_record_safe ();
120 MidiTrack::can_be_record_enabled ()
126 return Track::can_be_record_enabled ();
130 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
132 /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
133 and the diskstream must be set up to fill its buffers using the correct _note_mode.
135 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
136 mds->set_note_mode (_note_mode);
138 Track::set_diskstream (ds);
140 mds->reset_tracker ();
142 _diskstream->set_track (this);
143 #ifdef XXX_OLD_DESTRUCTIVE_API_XXX
144 if (Profile->get_trx()) {
145 _diskstream->set_destructive (false);
147 _diskstream->set_destructive (_mode == Destructive);
150 _diskstream->set_record_enabled (false);
152 _diskstream_data_recorded_connection.disconnect ();
153 mds->DataRecorded.connect_same_thread (
154 _diskstream_data_recorded_connection,
155 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
157 DiskstreamChanged (); /* EMIT SIGNAL */
160 boost::shared_ptr<MidiDiskstream>
161 MidiTrack::midi_diskstream() const
163 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
167 MidiTrack::set_state (const XMLNode& node, int version)
169 /* This must happen before Track::set_state(), as there will be a buffer
170 fill during that call, and we must fill buffers using the correct
173 if (!node.get_property (X_("note-mode"), _note_mode)) {
174 _note_mode = Sustained;
177 if (Track::set_state (node, version)) {
181 // No destructive MIDI tracks (yet?)
185 if (node.get_property ("input-active", yn)) {
186 set_input_active (yn);
189 ChannelMode playback_channel_mode = AllChannels;
190 ChannelMode capture_channel_mode = AllChannels;
192 node.get_property ("playback-channel-mode", playback_channel_mode);
193 node.get_property ("capture-channel-mode", capture_channel_mode);
195 if (node.get_property ("channel-mode", playback_channel_mode)) {
196 /* 3.0 behaviour where capture and playback modes were not separated */
197 capture_channel_mode = playback_channel_mode;
200 XMLProperty const * prop;
202 unsigned int playback_channel_mask = 0xffff;
203 unsigned int capture_channel_mask = 0xffff;
205 if ((prop = node.property ("playback-channel-mask")) != 0) {
206 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
208 if ((prop = node.property ("capture-channel-mask")) != 0) {
209 sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
211 if ((prop = node.property ("channel-mask")) != 0) {
212 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
213 capture_channel_mask = playback_channel_mask;
216 set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
217 set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
219 pending_state = const_cast<XMLNode*> (&node);
221 if (_session.state_of_the_state() & Session::Loading) {
222 _session.StateReady.connect_same_thread (
223 *this, boost::bind (&MidiTrack::set_state_part_two, this));
225 set_state_part_two ();
232 MidiTrack::state(bool full_state)
234 XMLNode& root (Track::state(full_state));
235 XMLNode* freeze_node;
238 if (_freeze_record.playlist) {
241 freeze_node = new XMLNode (X_("freeze-info"));
242 freeze_node->set_property ("playlist", _freeze_record.playlist->name());
243 freeze_node->set_property ("state", _freeze_record.state);
245 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
246 inode = new XMLNode (X_("processor"));
247 inode->set_property (X_("id"), id());
248 inode->add_child_copy ((*i)->state);
250 freeze_node->add_child_nocopy (*inode);
253 root.add_child_nocopy (*freeze_node);
256 root.set_property("playback-channel-mode", get_playback_channel_mode());
257 root.set_property("capture-channel-mode", get_capture_channel_mode());
258 snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
259 root.set_property("playback-channel-mask", std::string(buf));
260 snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
261 root.set_property("capture-channel-mask", std::string(buf));
263 root.set_property ("note-mode", _note_mode);
264 root.set_property ("step-editing", _step_editing);
265 root.set_property ("input-active", _input_active);
267 for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
268 if (boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) {
269 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c->second);
271 root.add_child_nocopy (ac->get_state ());
279 MidiTrack::set_state_part_two ()
283 /* This is called after all session state has been restored but before
284 have been made ports and connections are established.
287 if (pending_state == 0) {
291 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
293 _freeze_record.state = Frozen;
295 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
298 _freeze_record.processor_info.clear ();
301 if (fnode->get_property (X_("playlist"), str)) {
302 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (str);
304 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
306 _freeze_record.playlist.reset();
307 _freeze_record.state = NoFreeze;
312 fnode->get_property (X_("state"), _freeze_record.state);
314 XMLNodeConstIterator citer;
315 XMLNodeList clist = fnode->children();
317 for (citer = clist.begin(); citer != clist.end(); ++citer) {
318 if ((*citer)->name() != X_("processor")) {
322 if (!(*citer)->get_property (X_("id"), str)) {
326 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
327 boost::shared_ptr<Processor>());
329 _freeze_record.processor_info.push_back (frii);
333 if (midi_diskstream ()) {
334 midi_diskstream()->set_block_size (_session.get_block_size ());
341 MidiTrack::restore_controls ()
343 // TODO order events (CC before PGM to set banks)
344 for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
345 boost::shared_ptr<MidiTrack::MidiControl> mctrl = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second);
347 mctrl->restore_value();
353 MidiTrack::update_controls(const BufferSet& bufs)
355 const MidiBuffer& buf = bufs.get_midi(0);
356 for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
357 const Evoral::Event<framepos_t>& ev = *e;
358 const Evoral::Parameter param = midi_parameter(ev.buffer(), ev.size());
359 const boost::shared_ptr<Evoral::Control> control = this->control(param);
361 control->set_double(ev.value(), _session.transport_frame(), false);
366 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
370 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
372 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
374 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
375 framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
376 if (can_internal_playback_seek(::llabs(playback_distance))) {
377 /* TODO should declick, and/or note-off */
378 internal_playback_seek(playback_distance);
383 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
385 if (n_outputs().n_total() == 0 && _processors.empty()) {
391 if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
397 framepos_t transport_frame = _session.transport_frame();
400 framecnt_t playback_distance;
402 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
403 /* need to do this so that the diskstream sets its
404 playback distance to zero, thus causing diskstream::commit
407 BufferSet bufs; /* empty set - is OK, since nothing will happen */
409 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
410 need_butler = diskstream->commit (playback_distance);
414 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
416 fill_buffers_with_input (bufs, _input, nframes);
418 /* filter captured data before meter sees it */
419 _capture_filter.filter (bufs);
421 if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
422 _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
428 if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
429 need_butler = diskstream->commit (playback_distance);
434 /* note diskstream uses our filter to filter/map playback channels appropriately. */
436 if (monitoring_state() == MonitoringInput) {
438 /* not actually recording, but we want to hear the input material anyway,
439 at least potentially (depending on monitoring options)
442 /* because the playback buffer is event based and not a
443 * continuous stream, we need to make sure that we empty
444 * it of events every cycle to avoid it filling up with events
445 * read from disk, while we are actually monitoring input
448 diskstream->flush_playback (start_frame, end_frame);
453 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
455 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
457 /* final argument: don't waste time with automation if we're not recording or rolling */
459 process_output_buffers (bufs, start_frame, end_frame, nframes,
460 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
462 flush_processor_buffers_locked (nframes);
464 need_butler = diskstream->commit (playback_distance);
470 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
472 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
474 if (ret == 0 && _step_editing) {
475 push_midi_input_to_step_edit_ringbuffer (nframes);
482 MidiTrack::realtime_locate ()
484 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
490 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
491 (*i)->realtime_locate ();
494 midi_diskstream()->reset_tracker ();
498 MidiTrack::realtime_handle_transport_stopped ()
500 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
506 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
507 (*i)->realtime_handle_transport_stopped ();
512 MidiTrack::non_realtime_locate (framepos_t pos)
514 Track::non_realtime_locate(pos);
516 boost::shared_ptr<MidiPlaylist> playlist = midi_diskstream()->midi_playlist();
521 /* Get the top unmuted region at this position. */
522 boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(
523 playlist->top_unmuted_region_at(pos));
528 /* the source may be missing, but the control still referenced in the GUI */
529 if (!region->midi_source() || !region->model()) {
533 Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK);
538 /* Update track controllers based on its "automation". */
539 const framepos_t origin = region->position() - region->start();
540 BeatsFramesConverter bfc(_session.tempo_map(), origin);
541 for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
542 boost::shared_ptr<MidiTrack::MidiControl> tcontrol;
543 boost::shared_ptr<Evoral::Control> rcontrol;
544 if ((tcontrol = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) &&
545 (rcontrol = region->control(tcontrol->parameter()))) {
546 const Evoral::Beats pos_beats = bfc.from(pos - origin);
547 if (rcontrol->list()->size() > 0) {
548 tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()), Controllable::NoGroup);
555 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
557 PortSet& ports (_input->ports());
559 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
561 Buffer& b (p->get_buffer (nframes));
562 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
565 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
567 const Evoral::Event<framepos_t> ev(*e, false);
569 /* note on, since for step edit, note length is determined
573 if (ev.is_note_on()) {
574 /* we don't care about the time for this purpose */
575 _step_edit_ring_buffer.write (0, ev.event_type(), ev.size(), ev.buffer());
582 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
584 MidiBuffer& buf (bufs.get_midi (0));
586 update_controls (bufs);
588 // Append immediate events
590 if (_immediate_events.read_space()) {
592 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
593 name(), _immediate_events.read_space()));
595 /* write as many of the immediate events as we can, but give "true" as
596 * the last argument ("stop on overflow in destination") so that we'll
597 * ship the rest out next time.
599 * the Port::port_offset() + (nframes-1) argument puts all these events at the last
600 * possible position of the output buffer, so that we do not
601 * violate monotonicity when writing. Port::port_offset() will
602 * be non-zero if we're in a split process cycle.
604 _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
609 MidiTrack::export_stuff (BufferSet& buffers,
612 boost::shared_ptr<Processor> endpoint,
613 bool include_endpoint,
617 if (buffers.count().n_midi() == 0) {
621 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
623 Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
625 boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist>(diskstream->playlist());
630 buffers.get_midi(0).clear();
631 if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) {
635 //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
640 boost::shared_ptr<Region>
641 MidiTrack::bounce (InterThreadInfo& itt)
643 return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false);
646 boost::shared_ptr<Region>
647 MidiTrack::bounce_range (framepos_t start,
649 InterThreadInfo& itt,
650 boost::shared_ptr<Processor> endpoint,
651 bool include_endpoint)
653 vector<boost::shared_ptr<Source> > srcs;
654 return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
658 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
660 std::cerr << "MIDI freeze currently unsupported" << std::endl;
664 MidiTrack::unfreeze ()
666 _freeze_record.state = UnFrozen;
667 FreezeChange (); /* EMIT SIGNAL */
671 MidiTrack::set_note_mode (NoteMode m)
674 midi_diskstream()->set_note_mode(m);
678 MidiTrack::describe_parameter (Evoral::Parameter param)
680 const std::string str(instrument_info().get_controller_name(param));
681 return str.empty() ? Automatable::describe_parameter(param) : str;
685 MidiTrack::midi_panic()
687 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
688 for (uint8_t channel = 0; channel <= 0xF; channel++) {
689 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
690 write_immediate_event(3, ev);
691 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
692 write_immediate_event(3, ev);
693 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
694 write_immediate_event(3, ev);
698 /** \return true on success, false on failure (no buffer space left)
701 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
703 if (!Evoral::midi_event_is_valid(buf, size)) {
704 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
707 return (_immediate_events.write (0, Evoral::MIDI_EVENT, size, buf) == size);
711 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
713 switch (param.type()) {
714 case MidiCCAutomation:
715 case MidiPgmChangeAutomation:
716 case MidiPitchBenderAutomation:
717 case MidiChannelPressureAutomation:
718 case MidiNotePressureAutomation:
719 case MidiSystemExclusiveAutomation:
720 /* The track control for MIDI parameters is for immediate events to act
721 as a control surface, write/touch for them is not currently
725 Automatable::set_parameter_automation_state(param, state);
730 MidiTrack::MidiControl::restore_value ()
732 actually_set_value (get_value(), Controllable::NoGroup);
736 MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
738 const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
739 const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
742 if (isinf_local(val)) {
743 cerr << "MIDIControl value is infinity" << endl;
744 } else if (isnan_local(val)) {
745 cerr << "MIDIControl value is NaN" << endl;
746 } else if (val < desc.lower) {
747 cerr << "MIDIControl value is < " << desc.lower << endl;
748 } else if (val > desc.upper) {
749 cerr << "MIDIControl value is > " << desc.upper << endl;
758 assert(val <= desc.upper);
759 if ( ! _list || ! automation_playback()) {
761 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
762 switch(parameter.type()) {
763 case MidiCCAutomation:
764 ev[0] += MIDI_CMD_CONTROL;
765 ev[1] = parameter.id();
769 case MidiPgmChangeAutomation:
771 ev[0] += MIDI_CMD_PGM_CHANGE;
775 case MidiChannelPressureAutomation:
777 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
781 case MidiNotePressureAutomation:
782 ev[0] += MIDI_CMD_NOTE_PRESSURE;
783 ev[1] = parameter.id();
787 case MidiPitchBenderAutomation:
788 ev[0] += MIDI_CMD_BENDER;
789 ev[1] = 0x7F & int(val);
790 ev[2] = 0x7F & (int(val) >> 7);
796 _route->write_immediate_event(size, ev);
799 AutomationControl::actually_set_value(val, group_override);
803 MidiTrack::set_step_editing (bool yn)
805 if (_session.record_status() != Session::Disabled) {
809 if (yn != _step_editing) {
811 StepEditStatusChange (yn);
815 boost::shared_ptr<SMFSource>
816 MidiTrack::write_source (uint32_t)
818 return midi_diskstream()->write_source ();
822 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
824 if (_playback_filter.set_channel_mode(mode, mask)) {
825 _session.set_dirty();
830 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
832 if (_capture_filter.set_channel_mode(mode, mask)) {
833 _session.set_dirty();
838 MidiTrack::set_playback_channel_mask (uint16_t mask)
840 if (_playback_filter.set_channel_mask(mask)) {
841 _session.set_dirty();
846 MidiTrack::set_capture_channel_mask (uint16_t mask)
848 if (_capture_filter.set_channel_mask(mask)) {
849 _session.set_dirty();
853 boost::shared_ptr<MidiPlaylist>
854 MidiTrack::midi_playlist ()
856 return midi_diskstream()->midi_playlist ();
860 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
862 DataRecorded (src); /* EMIT SIGNAL */
866 MidiTrack::input_active () const
868 return _input_active;
872 MidiTrack::set_input_active (bool yn)
874 if (yn != _input_active) {
876 map_input_active (yn);
877 InputActiveChanged (); /* EMIT SIGNAL */
882 MidiTrack::map_input_active (bool yn)
888 PortSet& ports (_input->ports());
890 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
891 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
892 if (yn != mp->input_active()) {
893 mp->set_input_active (yn);
899 MidiTrack::track_input_active (IOChange change, void* /* src */)
901 if (change.type & IOChange::ConfigurationChanged) {
902 map_input_active (_input_active);
906 boost::shared_ptr<Diskstream>
907 MidiTrack::diskstream_factory (XMLNode const & node)
909 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
912 boost::shared_ptr<MidiBuffer>
913 MidiTrack::get_gui_feed_buffer () const
915 return midi_diskstream()->get_gui_feed_buffer ();
919 MidiTrack::act_on_mute ()
921 /* this is called right after our mute status has changed.
922 if we are now muted, send suitable output to shutdown
925 XXX we should should also stop all relevant note trackers.
928 /* If we haven't got a diskstream yet, there's nothing to worry about,
929 and we can't call get_channel_mask() anyway.
931 if (!midi_diskstream()) {
935 if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) {
936 /* only send messages for channels we are using */
938 uint16_t mask = _playback_filter.get_channel_mask();
940 for (uint8_t channel = 0; channel <= 0xF; channel++) {
942 if ((1<<channel) & mask) {
944 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
945 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
946 write_immediate_event (3, ev);
948 /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
949 silence notes that came from another non-muted track. */
953 /* Resolve active notes. */
954 midi_diskstream()->resolve_tracker(_immediate_events, Port::port_offset());
959 MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd)
961 Track::monitoring_changed (self, gcd);
963 /* monitoring state changed, so flush out any on notes at the
967 PortSet& ports (_output->ports());
969 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
970 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
972 mp->require_resolve ();
976 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
979 md->reset_tracker ();
984 MidiTrack::monitoring_state () const
986 MonitorState ms = Track::monitoring_state();
987 if (ms == MonitoringSilence) {
988 return MonitoringInput;