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.
20 #include "pbd/enumwriter.h"
21 #include "pbd/convert.h"
22 #include "evoral/midi_util.h"
24 #include "ardour/buffer_set.h"
25 #include "ardour/debug.h"
26 #include "ardour/delivery.h"
27 #include "ardour/meter.h"
28 #include "ardour/midi_diskstream.h"
29 #include "ardour/midi_playlist.h"
30 #include "ardour/midi_port.h"
31 #include "ardour/midi_track.h"
32 #include "ardour/port.h"
33 #include "ardour/processor.h"
34 #include "ardour/session.h"
35 #include "ardour/session_playlists.h"
36 #include "ardour/utils.h"
41 class InterThreadInfo;
48 using namespace ARDOUR;
51 MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
52 : Track (sess, name, flag, mode, DataType::MIDI)
53 , _immediate_events(1024) // FIXME: size?
54 , _step_edit_ring_buffer(64) // FIXME: size?
55 , _note_mode(Sustained)
56 , _step_editing (false)
57 , _input_active (true)
61 MidiTrack::~MidiTrack ()
72 _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
77 boost::shared_ptr<Diskstream>
78 MidiTrack::create_diskstream ()
80 MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
82 if (_flags & Hidden) {
83 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
85 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
88 assert(_mode != Destructive);
90 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
95 MidiTrack::set_record_enabled (bool yn, void *src)
101 Track::set_record_enabled (yn, src);
105 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
107 /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
108 and the diskstream must be set up to fill its buffers using the correct _note_mode.
110 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
111 mds->set_note_mode (_note_mode);
113 Track::set_diskstream (ds);
115 mds->reset_tracker ();
117 _diskstream->set_track (this);
118 _diskstream->set_destructive (_mode == Destructive);
119 _diskstream->set_record_enabled (false);
121 _diskstream_data_recorded_connection.disconnect ();
122 mds->DataRecorded.connect_same_thread (
123 _diskstream_data_recorded_connection,
124 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
126 DiskstreamChanged (); /* EMIT SIGNAL */
129 boost::shared_ptr<MidiDiskstream>
130 MidiTrack::midi_diskstream() const
132 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
136 MidiTrack::set_state (const XMLNode& node, int version)
138 const XMLProperty *prop;
140 /* This must happen before Track::set_state(), as there will be a buffer
141 fill during that call, and we must fill buffers using the correct
144 if ((prop = node.property (X_("note-mode"))) != 0) {
145 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
147 _note_mode = Sustained;
150 if (Track::set_state (node, version)) {
154 // No destructive MIDI tracks (yet?)
157 if ((prop = node.property ("input-active")) != 0) {
158 set_input_active (string_is_affirmative (prop->value()));
161 pending_state = const_cast<XMLNode*> (&node);
163 if (_session.state_of_the_state() & Session::Loading) {
164 _session.StateReady.connect_same_thread (
165 *this, boost::bind (&MidiTrack::set_state_part_two, this));
167 set_state_part_two ();
174 MidiTrack::state(bool full_state)
176 XMLNode& root (Track::state(full_state));
177 XMLNode* freeze_node;
180 if (_freeze_record.playlist) {
183 freeze_node = new XMLNode (X_("freeze-info"));
184 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
185 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
187 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
188 inode = new XMLNode (X_("processor"));
189 (*i)->id.print (buf, sizeof(buf));
190 inode->add_property (X_("id"), buf);
191 inode->add_child_copy ((*i)->state);
193 freeze_node->add_child_nocopy (*inode);
196 root.add_child_nocopy (*freeze_node);
199 root.add_property ("note-mode", enum_2_string (_note_mode));
200 root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
201 root.add_property ("input-active", (_input_active ? "yes" : "no"));
207 MidiTrack::set_state_part_two ()
211 LocaleGuard lg (X_("POSIX"));
213 /* This is called after all session state has been restored but before
214 have been made ports and connections are established.
217 if (pending_state == 0) {
221 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
223 _freeze_record.state = Frozen;
225 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
228 _freeze_record.processor_info.clear ();
230 if ((prop = fnode->property (X_("playlist"))) != 0) {
231 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
233 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
235 _freeze_record.playlist.reset();
236 _freeze_record.state = NoFreeze;
241 if ((prop = fnode->property (X_("state"))) != 0) {
242 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
245 XMLNodeConstIterator citer;
246 XMLNodeList clist = fnode->children();
248 for (citer = clist.begin(); citer != clist.end(); ++citer) {
249 if ((*citer)->name() != X_("processor")) {
253 if ((prop = (*citer)->property (X_("id"))) == 0) {
257 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
258 boost::shared_ptr<Processor>());
259 frii->id = prop->value ();
260 _freeze_record.processor_info.push_back (frii);
264 if (midi_diskstream ()) {
265 midi_diskstream()->set_block_size (_session.get_block_size ());
271 /** @param need_butler to be set to true if this track now needs the butler, otherwise it can be left alone
275 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
277 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
282 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
284 if (n_outputs().n_total() == 0 && _processors.empty()) {
293 framepos_t transport_frame = _session.transport_frame();
296 framecnt_t playback_distance;
298 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
299 /* need to do this so that the diskstream sets its
300 playback distance to zero, thus causing diskstream::commit
303 dret = diskstream->process (transport_frame, 0, playback_distance);
304 need_butler = diskstream->commit (playback_distance);
311 if ((dret = diskstream->process (transport_frame, nframes, playback_distance)) != 0) {
312 need_butler = diskstream->commit (playback_distance);
317 /* special condition applies */
319 if (_meter_point == MeterInput) {
320 _input->process_input (_meter, start_frame, end_frame, nframes);
323 if (monitoring_state() == MonitoringInput) {
325 /* not actually recording, but we want to hear the input material anyway,
326 at least potentially (depending on monitoring options)
329 /* because the playback buffer is event based and not a
330 * continuous stream, we need to make sure that we empty
331 * it of events every cycle to avoid it filling up with events
332 * read from disk, while we are actually monitoring input
335 diskstream->flush_playback (start_frame, end_frame);
337 passthru (start_frame, end_frame, nframes, 0);
342 XXX is it true that the earlier test on n_outputs()
343 means that we can avoid checking it again here? i think
344 so, because changing the i/o configuration of an IO
345 requires holding the AudioEngine lock, which we hold
346 while in the process() tree.
350 /* copy the diskstream data to all output buffers */
352 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
353 MidiBuffer& mbuf (bufs.get_midi (0));
355 /* we are a MIDI track, so we always start the chain with a
356 * single-MIDI-channel diskstream
363 diskstream->get_playback (mbuf, nframes);
365 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
367 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
369 /* final argument: don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
371 process_output_buffers (
372 bufs, start_frame, end_frame, nframes,
373 declick, (!diskstream->record_enabled() && !_session.transport_stopped())
377 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
378 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
380 d->flush_buffers (nframes);
384 need_butler = diskstream->commit (playback_distance);
390 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
392 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
394 if (ret == 0 && _step_editing) {
395 push_midi_input_to_step_edit_ringbuffer (nframes);
402 MidiTrack::realtime_locate ()
404 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
410 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
411 (*i)->realtime_locate ();
414 midi_diskstream()->reset_tracker ();
418 MidiTrack::realtime_handle_transport_stopped ()
420 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
426 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
427 (*i)->realtime_handle_transport_stopped ();
432 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
434 PortSet& ports (_input->ports());
436 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
438 Buffer& b (p->get_buffer (nframes));
439 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
442 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
444 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
446 /* note on, since for step edit, note length is determined
450 if (ev.is_note_on()) {
451 /* we don't care about the time for this purpose */
452 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
459 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
461 MidiBuffer& buf (bufs.get_midi (0));
463 // Append immediate events
465 if (_immediate_events.read_space()) {
467 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
468 name(), _immediate_events.read_space()));
470 /* write as many of the immediate events as we can, but give "true" as
471 * the last argument ("stop on overflow in destination") so that we'll
472 * ship the rest out next time.
474 * the (nframes-1) argument puts all these events at the last
475 * possible position of the output buffer, so that we do not
476 * violate monotonicity when writing.
479 _immediate_events.read (buf, 0, 1, nframes-1, true);
484 MidiTrack::export_stuff (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framecnt_t /*nframes*/,
485 boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/, bool /*forexport*/)
490 boost::shared_ptr<Region>
491 MidiTrack::bounce (InterThreadInfo& /*itt*/)
493 std::cerr << "MIDI bounce currently unsupported" << std::endl;
494 return boost::shared_ptr<Region> ();
498 boost::shared_ptr<Region>
499 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/,
500 boost::shared_ptr<Processor> /*endpoint*/, bool /*include_endpoint*/)
502 std::cerr << "MIDI bounce range currently unsupported" << std::endl;
503 return boost::shared_ptr<Region> ();
507 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
509 std::cerr << "MIDI freeze currently unsupported" << std::endl;
513 MidiTrack::unfreeze ()
515 _freeze_record.state = UnFrozen;
516 FreezeChange (); /* EMIT SIGNAL */
520 MidiTrack::set_note_mode (NoteMode m)
523 midi_diskstream()->set_note_mode(m);
527 MidiTrack::midi_panic()
529 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
530 for (uint8_t channel = 0; channel <= 0xF; channel++) {
531 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
532 write_immediate_event(3, ev);
533 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
534 write_immediate_event(3, ev);
535 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
536 write_immediate_event(3, ev);
540 /** \return true on success, false on failure (no buffer space left)
543 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
545 if (!Evoral::midi_event_is_valid(buf, size)) {
546 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
549 const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
550 return (_immediate_events.write(0, type, size, buf) == size);
554 MidiTrack::MidiControl::set_value(double val)
557 if (std::isinf(val)) {
558 cerr << "MIDIControl value is infinity" << endl;
559 } else if (std::isnan(val)) {
560 cerr << "MIDIControl value is NaN" << endl;
561 } else if (val < _list->parameter().min()) {
562 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
563 } else if (val > _list->parameter().max()) {
564 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
573 assert(val <= _list->parameter().max());
574 if ( ! automation_playback()) {
576 uint8_t ev[3] = { _list->parameter().channel(), uint8_t (val), 0 };
577 switch(_list->parameter().type()) {
578 case MidiCCAutomation:
579 ev[0] += MIDI_CMD_CONTROL;
580 ev[1] = _list->parameter().id();
584 case MidiPgmChangeAutomation:
586 ev[0] += MIDI_CMD_PGM_CHANGE;
590 case MidiChannelPressureAutomation:
592 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
596 case MidiPitchBenderAutomation:
597 ev[0] += MIDI_CMD_BENDER;
598 ev[1] = 0x7F & int(val);
599 ev[2] = 0x7F & (int(val) >> 7);
605 _route->write_immediate_event(size, ev);
608 AutomationControl::set_value(val);
612 MidiTrack::set_step_editing (bool yn)
614 if (_session.record_status() != Session::Disabled) {
618 if (yn != _step_editing) {
620 StepEditStatusChange (yn);
624 boost::shared_ptr<SMFSource>
625 MidiTrack::write_source (uint32_t)
627 return midi_diskstream()->write_source ();
631 MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask)
633 midi_diskstream()->set_channel_mode (mode, mask);
637 MidiTrack::get_channel_mode ()
639 return midi_diskstream()->get_channel_mode ();
643 MidiTrack::get_channel_mask ()
645 return midi_diskstream()->get_channel_mask ();
648 boost::shared_ptr<MidiPlaylist>
649 MidiTrack::midi_playlist ()
651 return midi_diskstream()->midi_playlist ();
655 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
657 DataRecorded (src); /* EMIT SIGNAL */
661 MidiTrack::input_active () const
663 return _input_active;
667 MidiTrack::set_input_active (bool yn)
669 if (yn != _input_active) {
671 map_input_active (yn);
672 InputActiveChanged (); /* EMIT SIGNAL */
677 MidiTrack::map_input_active (bool yn)
683 PortSet& ports (_input->ports());
685 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
686 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
687 if (yn != mp->input_active()) {
688 mp->set_input_active (yn);
694 MidiTrack::track_input_active (IOChange change, void* /* src */)
696 if (change.type & IOChange::ConfigurationChanged) {
697 map_input_active (_input_active);
701 boost::shared_ptr<Diskstream>
702 MidiTrack::diskstream_factory (XMLNode const & node)
704 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
707 boost::shared_ptr<MidiBuffer>
708 MidiTrack::get_gui_feed_buffer () const
710 return midi_diskstream()->get_gui_feed_buffer ();
714 MidiTrack::act_on_mute ()
716 /* this is called right after our mute status has changed.
717 if we are now muted, send suitable output to shutdown
720 XXX we should should also stop all relevant note trackers.
723 /* If we haven't got a diskstream yet, there's nothing to worry about,
724 and we can't call get_channel_mask() anyway.
726 if (!midi_diskstream()) {
731 /* only send messages for channels we are using */
733 uint16_t mask = get_channel_mask();
735 for (uint8_t channel = 0; channel <= 0xF; channel++) {
737 if ((1<<channel) & mask) {
739 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
740 uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
741 write_immediate_event (3, ev);
742 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
743 write_immediate_event (3, ev);
750 MidiTrack::set_monitoring (MonitorChoice mc)
752 if (mc != _monitoring) {
754 Track::set_monitoring (mc);
756 /* monitoring state changed, so flush out any on notes at the
760 PortSet& ports (_output->ports());
762 for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
763 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
765 mp->require_resolve ();
769 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
772 md->reset_tracker ();
778 MidiTrack::monitoring_state () const
780 MonitorState ms = Track::monitoring_state();
781 if (ms == MonitoringSilence) {
782 return MonitoringInput;