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/error.h"
22 #include "pbd/enumwriter.h"
23 #include "pbd/convert.h"
24 #include "midi++/events.h"
25 #include "evoral/midi_util.h"
27 #include "ardour/amp.h"
28 #include "ardour/buffer_set.h"
29 #include "ardour/debug.h"
30 #include "ardour/delivery.h"
31 #include "ardour/io_processor.h"
32 #include "ardour/meter.h"
33 #include "ardour/midi_diskstream.h"
34 #include "ardour/midi_playlist.h"
35 #include "ardour/midi_port.h"
36 #include "ardour/midi_region.h"
37 #include "ardour/midi_source.h"
38 #include "ardour/midi_track.h"
39 #include "ardour/panner.h"
40 #include "ardour/port.h"
41 #include "ardour/processor.h"
42 #include "ardour/route_group_specialized.h"
43 #include "ardour/session.h"
44 #include "ardour/session_playlists.h"
45 #include "ardour/utils.h"
50 using namespace ARDOUR;
53 MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
54 : Track (sess, name, flag, mode, DataType::MIDI)
55 , _immediate_events(1024) // FIXME: size?
56 , _step_edit_ring_buffer(64) // FIXME: size?
57 , _note_mode(Sustained)
58 , _step_editing (false)
60 , _input_active (true)
64 MidiTrack::~MidiTrack ()
75 _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
80 boost::shared_ptr<Diskstream>
81 MidiTrack::create_diskstream ()
83 MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0);
85 if (_flags & Hidden) {
86 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden);
88 dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable);
91 assert(_mode != Destructive);
93 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
98 MidiTrack::set_record_enabled (bool yn, void *src)
104 Track::set_record_enabled (yn, src);
108 MidiTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
110 Track::set_diskstream (ds);
112 midi_diskstream()->reset_tracker ();
114 _diskstream->set_track (this);
115 _diskstream->set_destructive (_mode == Destructive);
116 _diskstream->set_record_enabled (false);
118 _diskstream_data_recorded_connection.disconnect ();
119 boost::shared_ptr<MidiDiskstream> mds = boost::dynamic_pointer_cast<MidiDiskstream> (ds);
120 mds->DataRecorded.connect_same_thread (
121 _diskstream_data_recorded_connection,
122 boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
124 DiskstreamChanged (); /* EMIT SIGNAL */
127 boost::shared_ptr<MidiDiskstream>
128 MidiTrack::midi_diskstream() const
130 return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream);
134 MidiTrack::set_state (const XMLNode& node, int version)
136 const XMLProperty *prop;
138 if (Track::set_state (node, version)) {
142 // No destructive MIDI tracks (yet?)
145 if ((prop = node.property (X_("note-mode"))) != 0) {
146 _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode));
148 _note_mode = Sustained;
151 if ((prop = node.property ("midi-thru")) != 0) {
152 set_midi_thru (string_is_affirmative (prop->value()));
155 if ((prop = node.property ("input-active")) != 0) {
156 set_input_active (string_is_affirmative (prop->value()));
159 pending_state = const_cast<XMLNode*> (&node);
161 if (_session.state_of_the_state() & Session::Loading) {
162 _session.StateReady.connect_same_thread (
163 *this, boost::bind (&MidiTrack::set_state_part_two, this));
165 set_state_part_two ();
172 MidiTrack::state(bool full_state)
174 XMLNode& root (Track::state(full_state));
175 XMLNode* freeze_node;
178 if (_freeze_record.playlist) {
181 freeze_node = new XMLNode (X_("freeze-info"));
182 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
183 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
185 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
186 inode = new XMLNode (X_("processor"));
187 (*i)->id.print (buf, sizeof(buf));
188 inode->add_property (X_("id"), buf);
189 inode->add_child_copy ((*i)->state);
191 freeze_node->add_child_nocopy (*inode);
194 root.add_child_nocopy (*freeze_node);
197 root.add_property (X_("note-mode"), enum_2_string (_note_mode));
199 root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
200 root.add_property ("note-mode", enum_2_string (_note_mode));
201 root.add_property ("midi-thru", (_midi_thru ? "yes" : "no"));
202 root.add_property ("input-active", (_input_active ? "yes" : "no"));
208 MidiTrack::set_state_part_two ()
212 LocaleGuard lg (X_("POSIX"));
214 /* This is called after all session state has been restored but before
215 have been made ports and connections are established.
218 if (pending_state == 0) {
222 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
224 _freeze_record.state = Frozen;
226 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
229 _freeze_record.processor_info.clear ();
231 if ((prop = fnode->property (X_("playlist"))) != 0) {
232 boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
234 _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
236 _freeze_record.playlist.reset();
237 _freeze_record.state = NoFreeze;
242 if ((prop = fnode->property (X_("state"))) != 0) {
243 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
246 XMLNodeConstIterator citer;
247 XMLNodeList clist = fnode->children();
249 for (citer = clist.begin(); citer != clist.end(); ++citer) {
250 if ((*citer)->name() != X_("processor")) {
254 if ((prop = (*citer)->property (X_("id"))) == 0) {
258 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
259 boost::shared_ptr<Processor>());
260 frii->id = prop->value ();
261 _freeze_record.processor_info.push_back (frii);
265 if (midi_diskstream ()) {
266 midi_diskstream()->set_block_size (_session.get_block_size ());
273 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
275 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
280 boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
282 automation_snapshot (start_frame);
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);
310 if ((dret = diskstream->process (transport_frame, nframes, playback_distance)) != 0) {
311 need_butler = diskstream->commit (playback_distance);
316 /* special condition applies */
318 if (_meter_point == MeterInput) {
319 _input->process_input (_meter, start_frame, end_frame, nframes);
322 if (monitoring_state() == MonitoringInput) {
324 /* not actually recording, but we want to hear the input material anyway,
325 at least potentially (depending on monitoring options)
328 passthru (start_frame, end_frame, nframes, 0);
332 XXX is it true that the earlier test on n_outputs()
333 means that we can avoid checking it again here? i think
334 so, because changing the i/o configuration of an IO
335 requires holding the AudioEngine lock, which we hold
336 while in the process() tree.
340 /* copy the diskstream data to all output buffers */
342 //const size_t limit = n_process_buffers().n_audio();
343 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
344 MidiBuffer& mbuf (bufs.get_midi (0));
346 /* we are a MIDI track, so we always start the chain with a single-channel diskstream */
352 diskstream->get_playback (mbuf, nframes);
354 /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
356 write_out_of_band_data (bufs, start_frame, end_frame, nframes);
358 /* final argument: don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
360 process_output_buffers (
361 bufs, start_frame, end_frame, nframes,
362 declick, (!diskstream->record_enabled() && !_session.transport_stopped())
366 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
367 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
369 d->flush_buffers (nframes, end_frame - start_frame - 1);
373 need_butler = diskstream->commit (playback_distance);
379 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
381 int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
383 if (ret == 0 && _step_editing) {
384 push_midi_input_to_step_edit_ringbuffer (nframes);
391 MidiTrack::realtime_locate ()
393 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
399 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
400 (*i)->realtime_locate ();
403 midi_diskstream()->reset_tracker ();
407 MidiTrack::realtime_handle_transport_stopped ()
409 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
415 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
416 (*i)->realtime_handle_transport_stopped ();
421 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
423 PortSet& ports (_input->ports());
425 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
427 Buffer& b (p->get_buffer (nframes));
428 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
431 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
433 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
435 /* note on, since for step edit, note length is determined
439 if (ev.is_note_on()) {
440 /* we don't care about the time for this purpose */
441 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
448 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
450 MidiBuffer& buf (bufs.get_midi (0));
452 // Append immediate events
454 if (_immediate_events.read_space()) {
456 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
457 name(), _immediate_events.read_space()));
459 /* write as many of the immediate events as we can, but give "true" as
460 * the last argument ("stop on overflow in destination") so that we'll
461 * ship the rest out next time.
463 * the (nframes-1) argument puts all these events at the last
464 * possible position of the output buffer, so that we do not
465 * violate monotonicity when writing.
468 _immediate_events.read (buf, 0, 1, nframes-1, true);
471 // MIDI thru: send incoming data "through" output
472 if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) {
473 buf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes));
478 MidiTrack::export_stuff (BufferSet& /*bufs*/, framecnt_t /*nframes*/, framepos_t /*end_frame*/)
483 boost::shared_ptr<Region>
484 MidiTrack::bounce (InterThreadInfo& /*itt*/)
486 std::cerr << "MIDI bounce currently unsupported" << std::endl;
487 return boost::shared_ptr<Region> ();
491 boost::shared_ptr<Region>
492 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/, bool /*enable_processing*/)
494 std::cerr << "MIDI bounce range currently unsupported" << std::endl;
495 return boost::shared_ptr<Region> ();
499 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
501 std::cerr << "MIDI freeze currently unsupported" << std::endl;
505 MidiTrack::unfreeze ()
507 _freeze_record.state = UnFrozen;
508 FreezeChange (); /* EMIT SIGNAL */
512 MidiTrack::set_note_mode (NoteMode m)
515 midi_diskstream()->set_note_mode(m);
519 MidiTrack::midi_panic()
521 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
522 for (uint8_t channel = 0; channel <= 0xF; channel++) {
523 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
524 write_immediate_event(3, ev);
525 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
526 write_immediate_event(3, ev);
527 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
528 write_immediate_event(3, ev);
532 /** \return true on success, false on failure (no buffer space left)
535 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
537 if (!Evoral::midi_event_is_valid(buf, size)) {
538 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
541 const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
542 return (_immediate_events.write(0, type, size, buf) == size);
546 MidiTrack::MidiControl::set_value(double val)
550 cerr << "MIDIControl value is infinity" << endl;
551 } else if (isnan(val)) {
552 cerr << "MIDIControl value is NaN" << endl;
553 } else if (val < _list->parameter().min()) {
554 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
555 } else if (val > _list->parameter().max()) {
556 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
565 assert(val <= _list->parameter().max());
566 if ( ! automation_playback()) {
568 uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
569 switch(_list->parameter().type()) {
570 case MidiCCAutomation:
571 ev[0] += MIDI_CMD_CONTROL;
572 ev[1] = _list->parameter().id();
576 case MidiPgmChangeAutomation:
578 ev[0] += MIDI_CMD_PGM_CHANGE;
582 case MidiChannelPressureAutomation:
584 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
588 case MidiPitchBenderAutomation:
589 ev[0] += MIDI_CMD_BENDER;
590 ev[1] = 0x7F & int(val);
591 ev[2] = 0x7F & (int(val) >> 7);
597 _route->write_immediate_event(size, ev);
600 AutomationControl::set_value(val);
604 MidiTrack::set_step_editing (bool yn)
606 if (_session.record_status() != Session::Disabled) {
610 if (yn != _step_editing) {
612 StepEditStatusChange (yn);
617 MidiTrack::set_midi_thru (bool yn)
622 boost::shared_ptr<SMFSource>
623 MidiTrack::write_source (uint32_t)
625 return midi_diskstream()->write_source ();
629 MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask)
631 midi_diskstream()->set_channel_mode (mode, mask);
635 MidiTrack::get_channel_mode ()
637 return midi_diskstream()->get_channel_mode ();
641 MidiTrack::get_channel_mask ()
643 return midi_diskstream()->get_channel_mask ();
646 boost::shared_ptr<MidiPlaylist>
647 MidiTrack::midi_playlist ()
649 return midi_diskstream()->midi_playlist ();
653 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
655 DataRecorded (src); /* EMIT SIGNAL */
659 MidiTrack::input_active () const
661 return _input_active;
665 MidiTrack::set_input_active (bool yn)
667 if (yn != _input_active) {
669 map_input_active (yn);
670 InputActiveChanged (); /* EMIT SIGNAL */
675 MidiTrack::map_input_active (bool yn)
681 PortSet& ports (_input->ports());
683 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
684 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
685 if (yn != mp->input_active()) {
686 mp->set_input_active (yn);
692 MidiTrack::track_input_active (IOChange change, void* /* src */)
694 if (change.type & IOChange::ConfigurationChanged) {
695 map_input_active (_input_active);
699 boost::shared_ptr<Diskstream>
700 MidiTrack::diskstream_factory (XMLNode const & node)
702 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
705 boost::shared_ptr<MidiBuffer>
706 MidiTrack::get_gui_feed_buffer () const
708 return midi_diskstream()->get_gui_feed_buffer ();
712 MidiTrack::act_on_mute ()
714 /* this is called right after our mute status has changed.
715 if we are now muted, send suitable output to shutdown
718 XXX we should should also stop all relevant note trackers.
722 /* only send messages for channels we are using */
724 uint16_t mask = get_channel_mask();
726 for (uint8_t channel = 0; channel <= 0xF; channel++) {
728 if ((1<<channel) & mask) {
730 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
731 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
732 write_immediate_event (3, ev);
733 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
734 write_immediate_event (3, ev);
741 MidiTrack::set_monitoring (MonitorChoice mc)
743 Track::set_monitoring (mc);
745 boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
748 md->reset_tracker ();
753 MidiTrack::monitoring_state () const
755 /* Explicit requests */
757 if (_monitoring & MonitorInput) {
758 return MonitoringInput;
761 if (_monitoring & MonitorDisk) {
762 return MonitoringDisk;
765 if (_session.transport_rolling()) {
766 return MonitoringDisk;
769 /* the return value here doesn't mean that we're actually monitoring
770 * input, let alone input *audio*. but it means that we are NOT
771 * monitoring silence. this allows us to still hear any audio generated
772 * by using internal generation techniques
775 return MonitoringInput;