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_record_safe (bool yn, void *src)
117 if (_step_editing) { /* REQUIRES REVIEW */
121 Track::set_record_safe (yn, src);
125 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
127 /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
128 and the diskstream must be set up to fill its buffers using the correct _note_mode.
130 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
131 mds->set_note_mode (_note_mode);
133 Track::set_diskstream (ds);
135 mds->reset_tracker ();
137 _diskstream->set_track (this);
138 _diskstream->set_destructive (_mode == Destructive);
139 _diskstream->set_record_enabled (false);
141 _diskstream_data_recorded_connection.disconnect ();
142 mds->DataRecorded.connect_same_thread (
143 _diskstream_data_recorded_connection,
144 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
146 DiskstreamChanged (); /* EMIT SIGNAL */
149 boost::shared_ptr<MidiDiskstream>
150 MidiTrack::midi_diskstream() const
152 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
156 MidiTrack::set_state (const XMLNode& node, int version)
158 const XMLProperty *prop;
160 /* This must happen before Track::set_state(), as there will be a buffer
161 fill during that call, and we must fill buffers using the correct
164 if ((prop = node.property (X_("note-mode"))) != 0) {
165 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
167 _note_mode = Sustained;
170 if (Track::set_state (node, version)) {
174 // No destructive MIDI tracks (yet?)
177 if ((prop = node.property ("input-active")) != 0) {
178 set_input_active (string_is_affirmative (prop->value()));
181 ChannelMode playback_channel_mode = AllChannels;
182 ChannelMode capture_channel_mode = AllChannels;
184 if ((prop = node.property ("playback-channel-mode")) != 0) {
185 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
187 if ((prop = node.property ("capture-channel-mode")) != 0) {
188 capture_channel_mode = ChannelMode (string_2_enum(prop->value(), capture_channel_mode));
190 if ((prop = node.property ("channel-mode")) != 0) {
191 /* 3.0 behaviour where capture and playback modes were not separated */
192 playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
193 capture_channel_mode = playback_channel_mode;
196 unsigned int playback_channel_mask = 0xffff;
197 unsigned int capture_channel_mask = 0xffff;
199 if ((prop = node.property ("playback-channel-mask")) != 0) {
200 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
202 if ((prop = node.property ("capture-channel-mask")) != 0) {
203 sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
205 if ((prop = node.property ("channel-mask")) != 0) {
206 sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
207 capture_channel_mask = playback_channel_mask;
210 set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
211 set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
213 pending_state = const_cast<XMLNode*> (&node);
215 if (_session.state_of_the_state() & Session::Loading) {
216 _session.StateReady.connect_same_thread (
217 *this, boost::bind (&MidiTrack::set_state_part_two, this));
219 set_state_part_two ();
226 MidiTrack::state(bool full_state)
228 XMLNode& root (Track::state(full_state));
229 XMLNode* freeze_node;
232 if (_freeze_record.playlist) {
235 freeze_node = new XMLNode (X_("freeze-info"));
236 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
237 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
239 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
240 inode = new XMLNode (X_("processor"));
241 (*i)->id.print (buf, sizeof(buf));
242 inode->add_property (X_("id"), buf);
243 inode->add_child_copy ((*i)->state);
245 freeze_node->add_child_nocopy (*inode);
248 root.add_child_nocopy (*freeze_node);
251 root.add_property("playback_channel-mode", enum_2_string(get_playback_channel_mode()));
252 root.add_property("capture_channel-mode", enum_2_string(get_capture_channel_mode()));
253 snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
254 root.add_property("playback-channel-mask", buf);
255 snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
256 root.add_property("capture-channel-mask", buf);
258 root.add_property ("note-mode", enum_2_string (_note_mode));
259 root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
260 root.add_property ("input-active", (_input_active ? "yes" : "no"));
266 MidiTrack::set_state_part_two ()
270 LocaleGuard lg (X_("C"));
272 /* This is called after all session state has been restored but before
273 have been made ports and connections are established.
276 if (pending_state == 0) {
280 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
282 _freeze_record.state = Frozen;
284 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
287 _freeze_record.processor_info.clear ();
289 if ((prop = fnode->property (X_("playlist"))) != 0) {
290 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
292 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
294 _freeze_record.playlist.reset();
295 _freeze_record.state = NoFreeze;
300 if ((prop = fnode->property (X_("state"))) != 0) {
301 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
304 XMLNodeConstIterator citer;
305 XMLNodeList clist = fnode->children();
307 for (citer = clist.begin(); citer != clist.end(); ++citer) {
308 if ((*citer)->name() != X_("processor")) {
312 if ((prop = (*citer)->property (X_("id"))) == 0) {
316 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
317 boost::shared_ptr<Processor>());
318 frii->id = prop->value ();
319 _freeze_record.processor_info.push_back (frii);
323 if (midi_diskstream ()) {
324 midi_diskstream()->set_block_size (_session.get_block_size ());
331 MidiTrack::update_controls(const BufferSet& bufs)
333 const MidiBuffer& buf = bufs.get_midi(0);
334 for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
335 const Evoral::MIDIEvent<framepos_t>& ev = *e;
336 const Evoral::Parameter param = midi_parameter(ev.buffer(), ev.size());
337 const boost::shared_ptr<Evoral::Control> control = this->control(param);
339 control->set_double(ev.value(), _session.transport_frame(), false);
344 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
348 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
350 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
352 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
353 framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
354 if (can_internal_playback_seek(llabs(playback_distance))) {
355 /* TODO should declick, and/or note-off */
356 internal_playback_seek(playback_distance);
361 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
363 if (n_outputs().n_total() == 0 && _processors.empty()) {
369 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
375 framepos_t transport_frame = _session.transport_frame();
378 framecnt_t playback_distance;
380 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
381 /* need to do this so that the diskstream sets its
382 playback distance to zero, thus causing diskstream::commit
385 BufferSet bufs; /* empty set - is OK, since nothing will happen */
387 dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
388 need_butler = diskstream->commit (playback_distance);
392 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
394 fill_buffers_with_input (bufs, _input, nframes);
396 /* filter captured data before meter sees it */
397 _capture_filter.filter (bufs);
399 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
400 _meter->run (bufs, start_frame, end_frame, nframes, true);
406 if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
407 need_butler = diskstream->commit (playback_distance);
412 /* note diskstream uses our filter to filter/map playback channels appropriately. */
414 if (monitoring_state() == MonitoringInput) {
416 /* not actually recording, but we want to hear the input material anyway,
417 at least potentially (depending on monitoring options)
420 /* because the playback buffer is event based and not a
421 * continuous stream, we need to make sure that we empty
422 * it of events every cycle to avoid it filling up with events
423 * read from disk, while we are actually monitoring input
426 diskstream->flush_playback (start_frame, end_frame);
431 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
433 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
435 /* final argument: don't waste time with automation if we're not recording or rolling */
437 process_output_buffers (bufs, start_frame, end_frame, nframes,
438 declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
440 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
441 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
443 d->flush_buffers (nframes);
447 need_butler = diskstream->commit (playback_distance);
453 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
455 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
457 if (ret == 0 && _step_editing) {
458 push_midi_input_to_step_edit_ringbuffer (nframes);
465 MidiTrack::realtime_locate ()
467 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
473 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
474 (*i)->realtime_locate ();
477 midi_diskstream()->reset_tracker ();
481 MidiTrack::realtime_handle_transport_stopped ()
483 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
489 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
490 (*i)->realtime_handle_transport_stopped ();
495 MidiTrack::non_realtime_locate (framepos_t pos)
497 Track::non_realtime_locate(pos);
499 boost::shared_ptr<MidiPlaylist> playlist = midi_diskstream()->midi_playlist();
504 /* Get the top unmuted region at this position. */
505 boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(
506 playlist->top_unmuted_region_at(pos));
511 Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK);
516 /* Update track controllers based on its "automation". */
517 const framepos_t origin = region->position() - region->start();
518 BeatsFramesConverter bfc(_session.tempo_map(), origin);
519 for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
520 boost::shared_ptr<MidiTrack::MidiControl> tcontrol;
521 boost::shared_ptr<Evoral::Control> rcontrol;
522 if ((tcontrol = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) &&
523 (rcontrol = region->control(tcontrol->parameter()))) {
524 const Evoral::Beats pos_beats = bfc.from(pos - origin);
525 tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()));
531 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
533 PortSet& ports (_input->ports());
535 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
537 Buffer& b (p->get_buffer (nframes));
538 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
541 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
543 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
545 /* note on, since for step edit, note length is determined
549 if (ev.is_note_on()) {
550 /* we don't care about the time for this purpose */
551 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
558 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
560 MidiBuffer& buf (bufs.get_midi (0));
562 update_controls (bufs);
564 // Append immediate events
566 if (_immediate_events.read_space()) {
568 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
569 name(), _immediate_events.read_space()));
571 /* write as many of the immediate events as we can, but give "true" as
572 * the last argument ("stop on overflow in destination") so that we'll
573 * ship the rest out next time.
575 * the Port::port_offset() + (nframes-1) argument puts all these events at the last
576 * possible position of the output buffer, so that we do not
577 * violate monotonicity when writing. Port::port_offset() will
578 * be non-zero if we're in a split process cycle.
580 _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
585 MidiTrack::export_stuff (BufferSet& buffers,
588 boost::shared_ptr<Processor> endpoint,
589 bool include_endpoint,
593 if (buffers.count().n_midi() == 0) {
597 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
599 Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
601 boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist>(diskstream->playlist());
606 buffers.get_midi(0).clear();
607 if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) {
611 //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
616 boost::shared_ptr<Region>
617 MidiTrack::bounce (InterThreadInfo& itt)
619 return bounce_range (_session.current_start_frame(), _session.current_end_frame(), itt, main_outs(), false);
622 boost::shared_ptr<Region>
623 MidiTrack::bounce_range (framepos_t start,
625 InterThreadInfo& itt,
626 boost::shared_ptr<Processor> endpoint,
627 bool include_endpoint)
629 vector<boost::shared_ptr<Source> > srcs;
630 return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
634 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
636 std::cerr << "MIDI freeze currently unsupported" << std::endl;
640 MidiTrack::unfreeze ()
642 _freeze_record.state = UnFrozen;
643 FreezeChange (); /* EMIT SIGNAL */
647 MidiTrack::set_note_mode (NoteMode m)
650 midi_diskstream()->set_note_mode(m);
654 MidiTrack::describe_parameter (Evoral::Parameter param)
656 const std::string str(instrument_info().get_controller_name(param));
657 return str.empty() ? Automatable::describe_parameter(param) : str;
661 MidiTrack::midi_panic()
663 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
664 for (uint8_t channel = 0; channel <= 0xF; channel++) {
665 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
666 write_immediate_event(3, ev);
667 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
668 write_immediate_event(3, ev);
669 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
670 write_immediate_event(3, ev);
674 /** \return true on success, false on failure (no buffer space left)
677 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
679 if (!Evoral::midi_event_is_valid(buf, size)) {
680 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
683 const uint32_t type = midi_parameter_type(buf[0]);
684 return (_immediate_events.write (0, type, size, buf) == size);
688 MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
690 switch (param.type()) {
691 case MidiCCAutomation:
692 case MidiPgmChangeAutomation:
693 case MidiPitchBenderAutomation:
694 case MidiChannelPressureAutomation:
695 case MidiSystemExclusiveAutomation:
696 /* The track control for MIDI parameters is for immediate events to act
697 as a control surface, write/touch for them is not currently
701 Automatable::set_parameter_automation_state(param, state);
706 MidiTrack::MidiControl::set_value(double val)
708 const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
709 const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
712 if (isinf_local(val)) {
713 cerr << "MIDIControl value is infinity" << endl;
714 } else if (isnan_local(val)) {
715 cerr << "MIDIControl value is NaN" << endl;
716 } else if (val < desc.lower) {
717 cerr << "MIDIControl value is < " << desc.lower << endl;
718 } else if (val > desc.upper) {
719 cerr << "MIDIControl value is > " << desc.upper << endl;
728 assert(val <= desc.upper);
729 if ( ! _list || ! automation_playback()) {
731 uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
732 switch(parameter.type()) {
733 case MidiCCAutomation:
734 ev[0] += MIDI_CMD_CONTROL;
735 ev[1] = parameter.id();
739 case MidiPgmChangeAutomation:
741 ev[0] += MIDI_CMD_PGM_CHANGE;
745 case MidiChannelPressureAutomation:
747 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
751 case MidiPitchBenderAutomation:
752 ev[0] += MIDI_CMD_BENDER;
753 ev[1] = 0x7F & int(val);
754 ev[2] = 0x7F & (int(val) >> 7);
760 _route->write_immediate_event(size, ev);
763 AutomationControl::set_value(val);
767 MidiTrack::set_step_editing (bool yn)
769 if (_session.record_status() != Session::Disabled) {
773 if (yn != _step_editing) {
775 StepEditStatusChange (yn);
779 boost::shared_ptr<SMFSource>
780 MidiTrack::write_source (uint32_t)
782 return midi_diskstream()->write_source ();
786 MidiTrack::set_playback_channel_mode(ChannelMode mode, uint16_t mask)
788 if (_playback_filter.set_channel_mode(mode, mask)) {
789 _session.set_dirty();
794 MidiTrack::set_capture_channel_mode(ChannelMode mode, uint16_t mask)
796 if (_capture_filter.set_channel_mode(mode, mask)) {
797 _session.set_dirty();
802 MidiTrack::set_playback_channel_mask (uint16_t mask)
804 if (_playback_filter.set_channel_mask(mask)) {
805 _session.set_dirty();
810 MidiTrack::set_capture_channel_mask (uint16_t mask)
812 if (_capture_filter.set_channel_mask(mask)) {
813 _session.set_dirty();
817 boost::shared_ptr<MidiPlaylist>
818 MidiTrack::midi_playlist ()
820 return midi_diskstream()->midi_playlist ();
824 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
826 DataRecorded (src); /* EMIT SIGNAL */
830 MidiTrack::input_active () const
832 return _input_active;
836 MidiTrack::set_input_active (bool yn)
838 if (yn != _input_active) {
840 map_input_active (yn);
841 InputActiveChanged (); /* EMIT SIGNAL */
846 MidiTrack::map_input_active (bool yn)
852 PortSet& ports (_input->ports());
854 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
855 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
856 if (yn != mp->input_active()) {
857 mp->set_input_active (yn);
863 MidiTrack::track_input_active (IOChange change, void* /* src */)
865 if (change.type & IOChange::ConfigurationChanged) {
866 map_input_active (_input_active);
870 boost::shared_ptr<Diskstream>
871 MidiTrack::diskstream_factory (XMLNode const & node)
873 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
876 boost::shared_ptr<MidiBuffer>
877 MidiTrack::get_gui_feed_buffer () const
879 return midi_diskstream()->get_gui_feed_buffer ();
883 MidiTrack::act_on_mute ()
885 /* this is called right after our mute status has changed.
886 if we are now muted, send suitable output to shutdown
889 XXX we should should also stop all relevant note trackers.
892 /* If we haven't got a diskstream yet, there's nothing to worry about,
893 and we can't call get_channel_mask() anyway.
895 if (!midi_diskstream()) {
899 if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) {
900 /* only send messages for channels we are using */
902 uint16_t mask = _playback_filter.get_channel_mask();
904 for (uint8_t channel = 0; channel <= 0xF; channel++) {
906 if ((1<<channel) & mask) {
908 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
909 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
910 write_immediate_event (3, ev);
912 /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
913 silence notes that came from another non-muted track. */
917 /* Resolve active notes. */
918 midi_diskstream()->resolve_tracker(_immediate_events, 0);
923 MidiTrack::set_monitoring (MonitorChoice mc)
925 if (mc != _monitoring) {
927 Track::set_monitoring (mc);
929 /* monitoring state changed, so flush out any on notes at the
933 PortSet& ports (_output->ports());
935 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
936 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
938 mp->require_resolve ();
942 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
945 md->reset_tracker ();
951 MidiTrack::monitoring_state () const
953 MonitorState ms = Track::monitoring_state();
954 if (ms == MonitoringSilence) {
955 return MonitoringInput;