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 _diskstream->set_track (this);
113 _diskstream->set_destructive (_mode == Destructive);
115 _diskstream->set_record_enabled (false);
116 //_diskstream->monitor_input (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);
398 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
399 (*i)->realtime_locate ();
404 MidiTrack::realtime_handle_transport_stopped ()
406 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
411 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
412 (*i)->realtime_handle_transport_stopped ();
417 MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes)
419 PortSet& ports (_input->ports());
421 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
423 Buffer& b (p->get_buffer (nframes));
424 const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
427 for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
429 const Evoral::MIDIEvent<framepos_t> ev(*e, false);
431 /* note on, since for step edit, note length is determined
435 if (ev.is_note_on()) {
436 /* we don't care about the time for this purpose */
437 _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
444 MidiTrack::write_out_of_band_data (BufferSet& bufs, framepos_t /*start*/, framepos_t /*end*/, framecnt_t nframes)
446 MidiBuffer& buf (bufs.get_midi (0));
448 // Append immediate events
450 if (_immediate_events.read_space()) {
452 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
453 name(), _immediate_events.read_space()));
455 /* write as many of the immediate events as we can, but give "true" as
456 * the last argument ("stop on overflow in destination") so that we'll
457 * ship the rest out next time.
459 * the (nframes-1) argument puts all these events at the last
460 * possible position of the output buffer, so that we do not
461 * violate monotonicity when writing.
464 _immediate_events.read (buf, 0, 1, nframes-1, true);
467 // MIDI thru: send incoming data "through" output
468 if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) {
469 buf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes));
474 MidiTrack::export_stuff (BufferSet& /*bufs*/, framecnt_t /*nframes*/, framepos_t /*end_frame*/)
479 boost::shared_ptr<Region>
480 MidiTrack::bounce (InterThreadInfo& /*itt*/)
482 std::cerr << "MIDI bounce currently unsupported" << std::endl;
483 return boost::shared_ptr<Region> ();
487 boost::shared_ptr<Region>
488 MidiTrack::bounce_range (framepos_t /*start*/, framepos_t /*end*/, InterThreadInfo& /*itt*/, bool /*enable_processing*/)
490 std::cerr << "MIDI bounce range currently unsupported" << std::endl;
491 return boost::shared_ptr<Region> ();
495 MidiTrack::freeze_me (InterThreadInfo& /*itt*/)
497 std::cerr << "MIDI freeze currently unsupported" << std::endl;
501 MidiTrack::unfreeze ()
503 _freeze_record.state = UnFrozen;
504 FreezeChange (); /* EMIT SIGNAL */
508 MidiTrack::set_note_mode (NoteMode m)
511 midi_diskstream()->set_note_mode(m);
515 MidiTrack::midi_panic()
517 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
518 for (uint8_t channel = 0; channel <= 0xF; channel++) {
519 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
520 write_immediate_event(3, ev);
521 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
522 write_immediate_event(3, ev);
523 ev[1] = MIDI_CTL_RESET_CONTROLLERS;
524 write_immediate_event(3, ev);
528 /** \return true on success, false on failure (no buffer space left)
531 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
533 if (!Evoral::midi_event_is_valid(buf, size)) {
534 cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
537 const uint32_t type = EventTypeMap::instance().midi_event_type(buf[0]);
538 return (_immediate_events.write(0, type, size, buf) == size);
542 MidiTrack::MidiControl::set_value(double val)
546 cerr << "MIDIControl value is infinity" << endl;
547 } else if (isnan(val)) {
548 cerr << "MIDIControl value is NaN" << endl;
549 } else if (val < _list->parameter().min()) {
550 cerr << "MIDIControl value is < " << _list->parameter().min() << endl;
551 } else if (val > _list->parameter().max()) {
552 cerr << "MIDIControl value is > " << _list->parameter().max() << endl;
561 assert(val <= _list->parameter().max());
562 if ( ! automation_playback()) {
564 uint8_t ev[3] = { _list->parameter().channel(), int(val), 0 };
565 switch(_list->parameter().type()) {
566 case MidiCCAutomation:
567 ev[0] += MIDI_CMD_CONTROL;
568 ev[1] = _list->parameter().id();
572 case MidiPgmChangeAutomation:
574 ev[0] += MIDI_CMD_PGM_CHANGE;
578 case MidiChannelPressureAutomation:
580 ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
584 case MidiPitchBenderAutomation:
585 ev[0] += MIDI_CMD_BENDER;
586 ev[1] = 0x7F & int(val);
587 ev[2] = 0x7F & (int(val) >> 7);
593 _route->write_immediate_event(size, ev);
596 AutomationControl::set_value(val);
600 MidiTrack::set_step_editing (bool yn)
602 if (_session.record_status() != Session::Disabled) {
606 if (yn != _step_editing) {
608 StepEditStatusChange (yn);
613 MidiTrack::set_midi_thru (bool yn)
618 boost::shared_ptr<SMFSource>
619 MidiTrack::write_source (uint32_t)
621 return midi_diskstream()->write_source ();
625 MidiTrack::set_channel_mode (ChannelMode mode, uint16_t mask)
627 midi_diskstream()->set_channel_mode (mode, mask);
631 MidiTrack::get_channel_mode ()
633 return midi_diskstream()->get_channel_mode ();
637 MidiTrack::get_channel_mask ()
639 return midi_diskstream()->get_channel_mask ();
642 boost::shared_ptr<MidiPlaylist>
643 MidiTrack::midi_playlist ()
645 return midi_diskstream()->midi_playlist ();
649 MidiTrack::diskstream_data_recorded (boost::weak_ptr<MidiSource> src)
651 DataRecorded (src); /* EMIT SIGNAL */
655 MidiTrack::should_monitor () const
661 MidiTrack::send_silence () const
667 MidiTrack::input_active () const
669 return _input_active;
673 MidiTrack::set_input_active (bool yn)
675 if (yn != _input_active) {
677 map_input_active (yn);
678 InputActiveChanged (); /* EMIT SIGNAL */
683 MidiTrack::map_input_active (bool yn)
689 PortSet& ports (_input->ports());
691 for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
692 boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
693 if (yn != mp->input_active()) {
694 mp->set_input_active (yn);
700 MidiTrack::track_input_active (IOChange change, void* /* src */)
702 if (change.type & IOChange::ConfigurationChanged) {
703 map_input_active (_input_active);
707 boost::shared_ptr<Diskstream>
708 MidiTrack::diskstream_factory (XMLNode const & node)
710 return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, node));
713 boost::shared_ptr<MidiBuffer>
714 MidiTrack::get_gui_feed_buffer () const
716 return midi_diskstream()->get_gui_feed_buffer ();
720 MidiTrack::act_on_mute ()
722 /* this is called right after our mute status has changed.
723 if we are now muted, send suitable output to shutdown
726 XXX we should should also stop all relevant note trackers.
730 /* only send messages for channels we are using */
732 uint16_t mask = get_channel_mask();
734 for (uint8_t channel = 0; channel <= 0xF; channel++) {
736 if ((1<<channel) & mask) {
738 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
739 uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
740 write_immediate_event (3, ev);
741 ev[1] = MIDI_CTL_ALL_NOTES_OFF;
742 write_immediate_event (3, ev);