ardour
midi_track.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 Paul Davis
3  Author: David Robillard
4 
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.
9 
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.
14 
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.
18 */
19 #include <cmath>
20 
21 #ifdef COMPILER_MSVC
22 #include <float.h>
23 
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)
27 #else
28 #define isinf_local std::isinf
29 #define isnan_local std::isnan
30 #endif
31 
32 #include "pbd/enumwriter.h"
33 #include "pbd/convert.h"
34 #include "evoral/midi_util.h"
35 
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"
52 #include "ardour/utils.h"
53 
54 #include "i18n.h"
55 
56 namespace ARDOUR {
57 class InterThreadInfo;
58 class MidiSource;
59 class Region;
60 class SMFSource;
61 }
62 
63 using namespace std;
64 using namespace ARDOUR;
65 using namespace PBD;
66 
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)
74 {
75 }
76 
78 {
79 }
80 
81 int
83 {
84  if (Track::init ()) {
85  return -1;
86  }
87 
88  _input->changed.connect_same_thread (*this, boost::bind (&MidiTrack::track_input_active, this, _1, _2));
89 
90  return 0;
91 }
92 
95 {
97 
98  assert(_mode != Destructive);
99 
100  return boost::shared_ptr<Diskstream> (new MidiDiskstream (_session, name(), dflags));
101 }
102 
103 
104 void
105 MidiTrack::set_record_enabled (bool yn, void *src)
106 {
107  if (_step_editing) {
108  return;
109  }
110 
111  Track::set_record_enabled (yn, src);
112 }
113 
114 void
116 {
117  /* We have to do this here, as Track::set_diskstream will cause a buffer refill,
118  and the diskstream must be set up to fill its buffers using the correct _note_mode.
119  */
121  mds->set_note_mode (_note_mode);
122 
124 
125  mds->reset_tracker ();
126 
127  _diskstream->set_track (this);
128  _diskstream->set_destructive (_mode == Destructive);
129  _diskstream->set_record_enabled (false);
130 
132  mds->DataRecorded.connect_same_thread (
134  boost::bind (&MidiTrack::diskstream_data_recorded, this, _1));
135 
136  DiskstreamChanged (); /* EMIT SIGNAL */
137 }
138 
141 {
143 }
144 
145 int
146 MidiTrack::set_state (const XMLNode& node, int version)
147 {
148  const XMLProperty *prop;
149 
150  /* This must happen before Track::set_state(), as there will be a buffer
151  fill during that call, and we must fill buffers using the correct
152  _note_mode.
153  */
154  if ((prop = node.property (X_("note-mode"))) != 0) {
156  } else {
158  }
159 
160  if (Track::set_state (node, version)) {
161  return -1;
162  }
163 
164  // No destructive MIDI tracks (yet?)
165  _mode = Normal;
166 
167  if ((prop = node.property ("input-active")) != 0) {
169  }
170 
171  ChannelMode playback_channel_mode = AllChannels;
172  ChannelMode capture_channel_mode = AllChannels;
173 
174  if ((prop = node.property ("playback-channel-mode")) != 0) {
175  playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
176  }
177  if ((prop = node.property ("capture-channel-mode")) != 0) {
178  capture_channel_mode = ChannelMode (string_2_enum(prop->value(), capture_channel_mode));
179  }
180  if ((prop = node.property ("channel-mode")) != 0) {
181  /* 3.0 behaviour where capture and playback modes were not separated */
182  playback_channel_mode = ChannelMode (string_2_enum(prop->value(), playback_channel_mode));
183  capture_channel_mode = playback_channel_mode;
184  }
185 
186  unsigned int playback_channel_mask = 0xffff;
187  unsigned int capture_channel_mask = 0xffff;
188 
189  if ((prop = node.property ("playback-channel-mask")) != 0) {
190  sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
191  }
192  if ((prop = node.property ("capture-channel-mask")) != 0) {
193  sscanf (prop->value().c_str(), "0x%x", &capture_channel_mask);
194  }
195  if ((prop = node.property ("channel-mask")) != 0) {
196  sscanf (prop->value().c_str(), "0x%x", &playback_channel_mask);
197  capture_channel_mask = playback_channel_mask;
198  }
199 
200  set_playback_channel_mode (playback_channel_mode, playback_channel_mask);
201  set_capture_channel_mode (capture_channel_mode, capture_channel_mask);
202 
203  pending_state = const_cast<XMLNode*> (&node);
204 
206  _session.StateReady.connect_same_thread (
207  *this, boost::bind (&MidiTrack::set_state_part_two, this));
208  } else {
210  }
211 
212  return 0;
213 }
214 
215 XMLNode&
216 MidiTrack::state(bool full_state)
217 {
218  XMLNode& root (Track::state(full_state));
219  XMLNode* freeze_node;
220  char buf[64];
221 
222  if (_freeze_record.playlist) {
223  XMLNode* inode;
224 
225  freeze_node = new XMLNode (X_("freeze-info"));
226  freeze_node->add_property ("playlist", _freeze_record.playlist->name());
227  freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
228 
229  for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
230  inode = new XMLNode (X_("processor"));
231  (*i)->id.print (buf, sizeof(buf));
232  inode->add_property (X_("id"), buf);
233  inode->add_child_copy ((*i)->state);
234 
235  freeze_node->add_child_nocopy (*inode);
236  }
237 
238  root.add_child_nocopy (*freeze_node);
239  }
240 
241  root.add_property("playback_channel-mode", enum_2_string(get_playback_channel_mode()));
242  root.add_property("capture_channel-mode", enum_2_string(get_capture_channel_mode()));
243  snprintf (buf, sizeof(buf), "0x%x", get_playback_channel_mask());
244  root.add_property("playback-channel-mask", buf);
245  snprintf (buf, sizeof(buf), "0x%x", get_capture_channel_mask());
246  root.add_property("capture-channel-mask", buf);
247 
248  root.add_property ("note-mode", enum_2_string (_note_mode));
249  root.add_property ("step-editing", (_step_editing ? "yes" : "no"));
250  root.add_property ("input-active", (_input_active ? "yes" : "no"));
251 
252  return root;
253 }
254 
255 void
257 {
258  XMLNode* fnode;
259  XMLProperty* prop;
260  LocaleGuard lg (X_("C"));
261 
262  /* This is called after all session state has been restored but before
263  have been made ports and connections are established.
264  */
265 
266  if (pending_state == 0) {
267  return;
268  }
269 
270  if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
271 
273 
274  for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
275  delete *i;
276  }
278 
279  if ((prop = fnode->property (X_("playlist"))) != 0) {
280  boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
281  if (pl) {
283  } else {
286  return;
287  }
288  }
289 
290  if ((prop = fnode->property (X_("state"))) != 0) {
292  }
293 
294  XMLNodeConstIterator citer;
295  XMLNodeList clist = fnode->children();
296 
297  for (citer = clist.begin(); citer != clist.end(); ++citer) {
298  if ((*citer)->name() != X_("processor")) {
299  continue;
300  }
301 
302  if ((prop = (*citer)->property (X_("id"))) == 0) {
303  continue;
304  }
305 
306  FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
308  frii->id = prop->value ();
309  _freeze_record.processor_info.push_back (frii);
310  }
311  }
312 
313  if (midi_diskstream ()) {
314  midi_diskstream()->set_block_size (_session.get_block_size ());
315  }
316 
317  return;
318 }
319 
320 void
322 {
323  const MidiBuffer& buf = bufs.get_midi(0);
324  for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
325  const Evoral::MIDIEvent<framepos_t>& ev = *e;
326  const Evoral::Parameter param = midi_parameter(ev.buffer(), ev.size());
328  if (control) {
329  control->set_double(ev.value(), _session.transport_frame(), false);
330  }
331  }
332 }
333 
337 int
338 MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool& need_butler)
339 {
340  Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
341  if (!lm.locked()) {
343  framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
344  if (can_internal_playback_seek(llabs(playback_distance))) {
345  /* TODO should declick, and/or note-off */
346  internal_playback_seek(playback_distance);
347  }
348  return 0;
349  }
350 
352 
353  if (n_outputs().n_total() == 0 && _processors.empty()) {
354  return 0;
355  }
356 
357  if (!_active) {
358  silence (nframes);
359  if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
360  _meter->reset();
361  }
362  return 0;
363  }
364 
365  framepos_t transport_frame = _session.transport_frame();
366 
367  int dret;
368  framecnt_t playback_distance;
369 
370  if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
371  /* need to do this so that the diskstream sets its
372  playback distance to zero, thus causing diskstream::commit
373  to do nothing.
374  */
375  BufferSet bufs; /* empty set - is OK, since nothing will happen */
376 
377  dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
378  need_butler = diskstream->commit (playback_distance);
379  return dret;
380  }
381 
383 
384  fill_buffers_with_input (bufs, _input, nframes);
385 
386  /* filter captured data before meter sees it */
387  _capture_filter.filter (bufs);
388 
389  if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
390  _meter->run (bufs, start_frame, end_frame, nframes, true);
391  }
392 
393 
394  _silent = false;
395 
396  if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
397  need_butler = diskstream->commit (playback_distance);
398  silence (nframes);
399  return dret;
400  }
401 
402  /* note diskstream uses our filter to filter/map playback channels appropriately. */
403 
405 
406  /* not actually recording, but we want to hear the input material anyway,
407  at least potentially (depending on monitoring options)
408  */
409 
410  /* because the playback buffer is event based and not a
411  * continuous stream, we need to make sure that we empty
412  * it of events every cycle to avoid it filling up with events
413  * read from disk, while we are actually monitoring input
414  */
415 
416  diskstream->flush_playback (start_frame, end_frame);
417 
418  }
419 
420 
421  /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */
422 
423  write_out_of_band_data (bufs, start_frame, end_frame, nframes);
424 
425  /* final argument: don't waste time with automation if we're not recording or rolling */
426 
427  process_output_buffers (bufs, start_frame, end_frame, nframes,
428  declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
429 
430  for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
432  if (d) {
433  d->flush_buffers (nframes);
434  }
435  }
436 
437  need_butler = diskstream->commit (playback_distance);
438 
439  return 0;
440 }
441 
442 int
443 MidiTrack::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
444 {
445  int ret = Track::no_roll (nframes, start_frame, end_frame, state_changing);
446 
447  if (ret == 0 && _step_editing) {
449  }
450 
451  return ret;
452 }
453 
454 void
456 {
457  Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
458 
459  if (!lm.locked ()) {
460  return;
461  }
462 
463  for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
464  (*i)->realtime_locate ();
465  }
466 
467  midi_diskstream()->reset_tracker ();
468 }
469 
470 void
472 {
473  Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
474 
475  if (!lm.locked ()) {
476  return;
477  }
478 
479  for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
480  (*i)->realtime_handle_transport_stopped ();
481  }
482 }
483 
484 void
486 {
488 
490  if (!playlist) {
491  return;
492  }
493 
494  /* Get the top unmuted region at this position. */
496  playlist->top_unmuted_region_at(pos));
497  if (!region) {
498  return;
499  }
500 
501  Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK);
502  if (!lm.locked()) {
503  return;
504  }
505 
506  /* Update track controllers based on its "automation". */
507  const framepos_t origin = region->position() - region->start();
509  for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) {
512  if ((tcontrol = boost::dynamic_pointer_cast<MidiTrack::MidiControl>(c->second)) &&
513  (rcontrol = region->control(tcontrol->parameter()))) {
514  const Evoral::Beats pos_beats = bfc.from(pos - origin);
515  tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()));
516  }
517  }
518 }
519 
520 void
522 {
523  PortSet& ports (_input->ports());
524 
525  for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
526 
527  Buffer& b (p->get_buffer (nframes));
528  const MidiBuffer* const mb = dynamic_cast<MidiBuffer*>(&b);
529  assert (mb);
530 
531  for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) {
532 
533  const Evoral::MIDIEvent<framepos_t> ev(*e, false);
534 
535  /* note on, since for step edit, note length is determined
536  elsewhere
537  */
538 
539  if (ev.is_note_on()) {
540  /* we don't care about the time for this purpose */
541  _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer());
542  }
543  }
544  }
545 }
546 
547 void
549 {
550  MidiBuffer& buf (bufs.get_midi (0));
551 
552  update_controls (bufs);
553 
554  // Append immediate events
555 
557 
558  DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
560 
561  /* write as many of the immediate events as we can, but give "true" as
562  * the last argument ("stop on overflow in destination") so that we'll
563  * ship the rest out next time.
564  *
565  * the Port::port_offset() + (nframes-1) argument puts all these events at the last
566  * possible position of the output buffer, so that we do not
567  * violate monotonicity when writing. Port::port_offset() will
568  * be non-zero if we're in a split process cycle.
569  */
570  _immediate_events.read (buf, 0, 1, Port::port_offset() + nframes - 1, true);
571  }
572 }
573 
574 int
577  framecnt_t nframes,
579  bool include_endpoint,
580  bool for_export,
581  bool for_freeze)
582 {
583  if (buffers.count().n_midi() == 0) {
584  return -1;
585  }
586 
588 
589  Glib::Threads::RWLock::ReaderLock rlock (_processor_lock);
590 
592  if (!mpl) {
593  return -2;
594  }
595 
596  buffers.get_midi(0).clear();
597  if (mpl->read(buffers.get_midi(0), start, nframes, 0) != nframes) {
598  return -1;
599  }
600 
601  //bounce_process (buffers, start, nframes, endpoint, include_endpoint, for_export, for_freeze);
602 
603  return 0;
604 }
605 
608 {
610 }
611 
614  framepos_t end,
615  InterThreadInfo& itt,
617  bool include_endpoint)
618 {
619  vector<boost::shared_ptr<Source> > srcs;
620  return _session.write_one_track (*this, start, end, false, srcs, itt, endpoint, include_endpoint, false, false);
621 }
622 
623 void
625 {
626  std::cerr << "MIDI freeze currently unsupported" << std::endl;
627 }
628 
629 void
631 {
633  FreezeChange (); /* EMIT SIGNAL */
634 }
635 
636 void
638 {
639  _note_mode = m;
640  midi_diskstream()->set_note_mode(m);
641 }
642 
643 std::string
645 {
646  const std::string str(instrument_info().get_controller_name(param));
647  return str.empty() ? Automatable::describe_parameter(param) : str;
648 }
649 
650 void
652 {
653  DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
654  for (uint8_t channel = 0; channel <= 0xF; channel++) {
655  uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), ((uint8_t) MIDI_CTL_SUSTAIN), 0 };
656  write_immediate_event(3, ev);
657  ev[1] = MIDI_CTL_ALL_NOTES_OFF;
658  write_immediate_event(3, ev);
660  write_immediate_event(3, ev);
661  }
662 }
663 
666 bool
667 MidiTrack::write_immediate_event(size_t size, const uint8_t* buf)
668 {
669  if (!Evoral::midi_event_is_valid(buf, size)) {
670  cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
671  return false;
672  }
673  const uint32_t type = midi_parameter_type(buf[0]);
674  return (_immediate_events.write (0, type, size, buf) == size);
675 }
676 
677 void
679 {
680  switch (param.type()) {
681  case MidiCCAutomation:
686  /* The track control for MIDI parameters is for immediate events to act
687  as a control surface, write/touch for them is not currently
688  supported. */
689  return;
690  default:
692  }
693 }
694 
695 void
697 {
698  const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
700 
701  bool valid = false;
702  if (isinf_local(val)) {
703  cerr << "MIDIControl value is infinity" << endl;
704  } else if (isnan_local(val)) {
705  cerr << "MIDIControl value is NaN" << endl;
706  } else if (val < desc.lower) {
707  cerr << "MIDIControl value is < " << desc.lower << endl;
708  } else if (val > desc.upper) {
709  cerr << "MIDIControl value is > " << desc.upper << endl;
710  } else {
711  valid = true;
712  }
713 
714  if (!valid) {
715  return;
716  }
717 
718  assert(val <= desc.upper);
719  if ( ! _list || ! automation_playback()) {
720  size_t size = 3;
721  uint8_t ev[3] = { parameter.channel(), uint8_t (val), 0 };
722  switch(parameter.type()) {
723  case MidiCCAutomation:
724  ev[0] += MIDI_CMD_CONTROL;
725  ev[1] = parameter.id();
726  ev[2] = int(val);
727  break;
728 
730  size = 2;
731  ev[0] += MIDI_CMD_PGM_CHANGE;
732  ev[1] = int(val);
733  break;
734 
736  size = 2;
737  ev[0] += MIDI_CMD_CHANNEL_PRESSURE;
738  ev[1] = int(val);
739  break;
740 
742  ev[0] += MIDI_CMD_BENDER;
743  ev[1] = 0x7F & int(val);
744  ev[2] = 0x7F & (int(val) >> 7);
745  break;
746 
747  default:
748  assert(false);
749  }
750  _route->write_immediate_event(size, ev);
751  }
752 
754 }
755 
756 void
758 {
760  return;
761  }
762 
763  if (yn != _step_editing) {
764  _step_editing = yn;
766  }
767 }
768 
771 {
772  return midi_diskstream()->write_source ();
773 }
774 
775 void
777 {
778  if (_playback_filter.set_channel_mode(mode, mask)) {
780  }
781 }
782 
783 void
785 {
786  if (_capture_filter.set_channel_mode(mode, mask)) {
788  }
789 }
790 
791 void
793 {
796  }
797 }
798 
799 void
801 {
802  if (_capture_filter.set_channel_mask(mask)) {
804  }
805 }
806 
809 {
810  return midi_diskstream()->midi_playlist ();
811 }
812 
813 void
815 {
816  DataRecorded (src); /* EMIT SIGNAL */
817 }
818 
819 bool
821 {
822  return _input_active;
823 }
824 
825 void
827 {
828  if (yn != _input_active) {
829  _input_active = yn;
830  map_input_active (yn);
831  InputActiveChanged (); /* EMIT SIGNAL */
832  }
833 }
834 
835 void
837 {
838  if (!_input) {
839  return;
840  }
841 
842  PortSet& ports (_input->ports());
843 
844  for (PortSet::iterator p = ports.begin(DataType::MIDI); p != ports.end(DataType::MIDI); ++p) {
846  if (yn != mp->input_active()) {
847  mp->set_input_active (yn);
848  }
849  }
850 }
851 
852 void
853 MidiTrack::track_input_active (IOChange change, void* /* src */)
854 {
855  if (change.type & IOChange::ConfigurationChanged) {
857  }
858 }
859 
862 {
864 }
865 
868 {
869  return midi_diskstream()->get_gui_feed_buffer ();
870 }
871 
872 void
874 {
875  /* this is called right after our mute status has changed.
876  if we are now muted, send suitable output to shutdown
877  all our notes.
878 
879  XXX we should should also stop all relevant note trackers.
880  */
881 
882  /* If we haven't got a diskstream yet, there's nothing to worry about,
883  and we can't call get_channel_mask() anyway.
884  */
885  if (!midi_diskstream()) {
886  return;
887  }
888 
889  if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) {
890  /* only send messages for channels we are using */
891 
892  uint16_t mask = _playback_filter.get_channel_mask();
893 
894  for (uint8_t channel = 0; channel <= 0xF; channel++) {
895 
896  if ((1<<channel) & mask) {
897 
898  DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers mute message to channel %2\n", name(), channel+1));
899  uint8_t ev[3] = { ((uint8_t) (MIDI_CMD_CONTROL | channel)), MIDI_CTL_SUSTAIN, 0 };
900  write_immediate_event (3, ev);
901 
902  /* Note we do not send MIDI_CTL_ALL_NOTES_OFF here, since this may
903  silence notes that came from another non-muted track. */
904  }
905  }
906 
907  /* Resolve active notes. */
908  midi_diskstream()->resolve_tracker(_immediate_events, 0);
909  }
910 }
911 
912 void
914 {
915  if (mc != _monitoring) {
916 
918 
919  /* monitoring state changed, so flush out any on notes at the
920  * port level.
921  */
922 
923  PortSet& ports (_output->ports());
924 
925  for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
927  if (mp) {
928  mp->require_resolve ();
929  }
930  }
931 
933 
934  if (md) {
935  md->reset_tracker ();
936  }
937  }
938 }
939 
942 {
944  if (ms == MonitoringSilence) {
945  return MonitoringInput;
946  }
947  return ms;
948 }
949 
int roll(pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool &need_butler)
Definition: midi_track.cc:338
void set_record_enabled(bool yn, void *src)
Definition: track.cc:273
ARDOUR::Session & _session
MeterPoint _meter_point
Definition: route.h:538
boost::shared_ptr< Diskstream > create_diskstream()
Definition: midi_track.cc:94
float lower
Minimum value (in Hz, for frequencies)
MidiBuffer & get_midi(size_t i)
Definition: buffer_set.h:107
void set_monitoring(MonitorChoice)
Definition: midi_track.cc:913
boost::shared_ptr< Region > write_one_track(Track &, framepos_t start, framepos_t end, bool overwrite, std::vector< boost::shared_ptr< Source > > &, InterThreadInfo &wot, boost::shared_ptr< Processor > endpoint, bool include_endpoint, bool for_export, bool for_freeze)
Definition: session.cc:4586
void write_out_of_band_data(BufferSet &bufs, framepos_t start_frame, framepos_t end_frame, framecnt_t nframes)
Definition: midi_track.cc:548
FreezeRecord _freeze_record
Definition: track.h:214
const std::string & value() const
Definition: xml++.h:159
NoteMode
Definition: types.h:204
bool _silent
Definition: route.h:550
ConnectionList _list
Definition: signals.h:179
framecnt_t read(Evoral::EventSink< framepos_t > &buf, framepos_t start, framecnt_t cnt, uint32_t chan_n=0, MidiChannelFilter *filter=NULL)
PBD::Signal0< void > DiskstreamChanged
Definition: track.h:163
NoteMode _note_mode
Definition: midi_track.h:145
virtual int set_state(const XMLNode &, int version)
Definition: track.cc:108
#define enum_2_string(e)
Definition: enumwriter.h:97
#define MIDI_CMD_CHANNEL_PRESSURE
Definition: midi_events.h:112
void flush_buffers(framecnt_t nframes)
Definition: delivery.cc:450
static bool midi_event_is_valid(const uint8_t *buffer, size_t len)
Definition: midi_util.h:113
bool is_note_on() const
Definition: MIDIEvent.hpp:68
PBD::Signal0< void > FreezeChange
Definition: track.h:164
int process(BufferSet &, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_diskstream)
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
int set_state(const XMLNode &, int version)
Definition: midi_track.cc:146
boost::shared_ptr< MidiDiskstream > midi_diskstream() const
Definition: midi_track.cc:140
int no_roll(pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
Definition: midi_track.cc:443
bool commit(framecnt_t nframes)
#define MIDI_CMD_PGM_CHANGE
Definition: midi_events.h:111
static const MutePoint AllPoints
Definition: mute_master.h:45
uint16_t get_channel_mask() const
TempoMap & tempo_map()
Definition: session.h:596
LIBARDOUR_API uint64_t MidiIO
Definition: debug.cc:44
virtual void set_monitoring(MonitorChoice)
Definition: track.cc:1017
boost::shared_ptr< Control > control(const Parameter &id, bool create_if_missing=false)
Definition: ControlSet.cpp:73
uint32_t pframes_t
Definition: types.h:61
boost::shared_ptr< MidiBuffer > get_gui_feed_buffer() const
Definition: midi_track.cc:867
XMLNode * add_child_copy(const XMLNode &)
Definition: xml++.cc:363
Definition: Beats.hpp:239
void non_realtime_locate(framepos_t)
Definition: midi_track.cc:485
bool _active
Definition: route.h:510
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
virtual void set_parameter_automation_state(Evoral::Parameter param, AutoState)
Definition: midi_track.cc:678
ProcessorList _processors
Definition: route.h:517
#define MIDI_CMD_BENDER
Definition: midi_events.h:113
uint32_t write(Time time, Evoral::EventType type, uint32_t size, const uint8_t *buf)
boost::shared_ptr< Region > bounce(InterThreadInfo &)
Definition: midi_track.cc:607
MonitorChoice
Definition: types.h:386
uint16_t get_playback_channel_mask() const
Definition: midi_track.h:119
ChannelMode
Definition: types.h:209
RecordState record_status() const
Definition: session.h:276
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
virtual int no_roll(pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool state_changing)
Definition: track.cc:381
virtual void set_parameter_automation_state(Evoral::Parameter param, AutoState)
Definition: automatable.cc:272
void set_record_enabled(bool yn, void *src)
Definition: midi_track.cc:105
MidiChannelFilter _capture_filter
Definition: midi_track.h:149
void set_capture_channel_mode(ChannelMode mode, uint16_t mask)
Definition: midi_track.cc:784
void set_diskstream(boost::shared_ptr< Diskstream >)
Definition: midi_track.cc:115
void realtime_handle_transport_stopped()
Definition: midi_track.cc:471
PBD::ScopedConnection _diskstream_data_recorded_connection
Definition: midi_track.h:165
void set_playback_channel_mask(uint16_t mask)
Definition: midi_track.cc:792
uint32_t n_midi() const
Definition: chan_count.h:66
boost::shared_ptr< Evoral::Control > control(const Evoral::Parameter &id, bool create=false)
Definition: midi_region.cc:366
static framecnt_t port_offset()
Definition: port.h:131
#define origin
boost::shared_ptr< Playlist > playlist
Definition: track.h:197
boost::shared_ptr< PeakMeter > _meter
Definition: route.h:590
boost::shared_ptr< Region > top_unmuted_region_at(framepos_t frame)
Definition: playlist.cc:1744
#define MIDI_CTL_RESET_CONTROLLERS
Definition: midi_events.h:98
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
PBD::Signal1< void, boost::weak_ptr< MidiSource > > DataRecorded
Glib::Threads::Mutex _control_lock
Definition: ControlSet.hpp:76
PBD::Signal0< void > StateReady
Definition: session.h:442
void realtime_locate()
Definition: midi_track.cc:455
void flush_playback(framepos_t, framepos_t)
PBD::Signal1< void, bool > StepEditStatusChange
Definition: midi_track.h:107
MidiRingBuffer< framepos_t > _step_edit_ring_buffer
Definition: midi_track.h:144
Evoral::ParameterDescriptor descriptor(const Evoral::Parameter &param) const
uint16_t get_capture_channel_mask() const
Definition: midi_track.h:120
XMLNode * pending_state
Definition: track.h:215
Evoral::Parameter midi_parameter(const uint8_t *buf, const uint32_t len)
void set_capture_channel_mask(uint16_t mask)
Definition: midi_track.cc:800
void set_note_mode(NoteMode m)
Definition: midi_track.cc:637
TrackMode
Definition: types.h:198
#define MIDI_CMD_CONTROL
Definition: midi_events.h:110
#define X_(Text)
Definition: i18n.h:13
int64_t framecnt_t
Definition: types.h:76
XMLProperty * property(const char *)
Definition: xml++.cc:413
PBD::Signal0< void > InputActiveChanged
Definition: midi_track.h:135
void set_note_mode(NoteMode m)
boost::shared_ptr< IO > _output
Definition: route.h:508
#define string_2_enum(str, e)
Definition: enumwriter.h:98
float upper
Maximum value (in Hz, for frequencies)
void silence(framecnt_t)
Definition: route.cc:2894
void set_input_active(bool yn)
Definition: midi_port.cc:301
uint32_t size() const
Definition: Event.hpp:134
void set_input_active(bool)
Definition: midi_track.cc:826
enum ARDOUR::IOChange::Type type
MidiRingBuffer< framepos_t > _immediate_events
Definition: midi_track.h:143
std::vector< FreezeRecordProcessorInfo * > processor_info
Definition: track.h:198
void set_playback_channel_mode(ChannelMode mode, uint16_t mask)
Definition: midi_track.cc:776
virtual std::string describe_parameter(Evoral::Parameter param)
Definition: automatable.cc:160
size_t read(MidiBuffer &dst, framepos_t start, framepos_t end, framecnt_t offset=0, bool stop_on_overflow_in_destination=false)
bool string_is_affirmative(const std::string &str)
Definition: convert.cc:282
void set_state_part_two()
Definition: midi_track.cc:256
#define isnan_local
Definition: midi_track.cc:29
int internal_playback_seek(framecnt_t)
Definition: track.cc:686
boost::shared_ptr< Delivery > main_outs() const
Definition: route.h:237
StateOfTheState state_of_the_state() const
Definition: session.h:480
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
std::string describe_parameter(Evoral::Parameter param)
Definition: midi_track.cc:644
MonitorState
Definition: types.h:393
#define MIDI_CTL_SUSTAIN
Definition: midi_events.h:65
boost::shared_ptr< Region > bounce_range(framepos_t start, framepos_t end, InterThreadInfo &iti, boost::shared_ptr< Processor > endpoint, bool include_endpoint)
Definition: midi_track.cc:613
#define isinf_local
Definition: midi_track.cc:28
frameoffset_t calculate_playback_distance(pframes_t nframes)
ChanCount n_outputs() const
Definition: route.h:93
boost::shared_ptr< Playlist > playlist()
Definition: track.cc:590
void freeze_me(InterThreadInfo &)
Definition: midi_track.cc:624
bool record_enabled() const
Definition: diskstream.h:106
void update_controls(const BufferSet &bufs)
Definition: midi_track.cc:321
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
int64_t framepos_t
Definition: types.h:66
MonitorChoice _monitoring
Definition: track.h:178
virtual boost::shared_ptr< Diskstream > diskstream_factory(XMLNode const &)
Definition: midi_track.cc:861
static EventTypeMap & instance()
LIBARDOUR_API XMLNode * find_named_node(const XMLNode &node, std::string name)
void filter(BufferSet &bufs)
void set_step_editing(bool yn)
Definition: midi_track.cc:757
void map_input_active(bool)
Definition: midi_track.cc:836
const Parameter & parameter() const
Definition: Control.hpp:69
framepos_t position() const
Definition: region.h:112
uint8_t type() const
Definition: MIDIEvent.hpp:60
bool write_immediate_event(size_t size, const uint8_t *buf)
Definition: midi_track.cc:667
bool muted() const
Definition: route.cc:1031
XMLProperty * add_property(const char *name, const std::string &value)
void diskstream_data_recorded(boost::weak_ptr< MidiSource >)
Definition: midi_track.cc:814
BufferSet & get_route_buffers(ChanCount count=ChanCount::ZERO, bool silence=true)
Definition: session.cc:4857
boost::shared_ptr< IO > _input
Definition: route.h:507
bool transport_stopped() const
Definition: session.h:591
MonitorState monitoring_state() const
Definition: track.cc:894
boost::shared_ptr< SMFSource > write_source(uint32_t n=0)
Definition: midi_track.cc:770
const char * name
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
int can_internal_playback_seek(framecnt_t)
Definition: track.cc:680
MonitorState monitoring_state() const
Definition: midi_track.cc:941
bool set_channel_mask(uint16_t mask)
uint32_t id() const
Definition: Parameter.hpp:49
pframes_t get_block_size() const
Definition: session.h:393
framepos_t current_end_frame() const
Definition: session.cc:5048
XMLNode & state(bool full)
Definition: track.cc:96
TrackMode _mode
Definition: track.h:176
PBD::Signal1< void, boost::weak_ptr< MidiSource > > DataRecorded
Definition: midi_track.h:127
framepos_t current_start_frame() const
Definition: session.cc:5042
Definition: xml++.h:95
boost::shared_ptr< ControlList > list()
Definition: Control.hpp:66
std::string name() const
const ChanCount & count() const
Definition: buffer_set.h:87
ChannelMode get_capture_channel_mode() const
Definition: midi_track.h:118
virtual void clear()
Definition: buffer.h:70
framecnt_t check_initial_delay(framecnt_t nframes, framepos_t &)
Definition: track.cc:981
uint32_t type() const
Definition: Parameter.hpp:47
bool input_active() const
Definition: midi_track.cc:820
Definition: debug.h:30
Pass through all channel information unmodified.
Definition: types.h:210
uint16_t value() const
Definition: MIDIEvent.hpp:108
double to_double() const
Definition: Beats.hpp:185
TrackMode mode() const
Definition: track.h:49
void non_realtime_locate(framepos_t)
Definition: track.cc:698
int init()
Definition: track.cc:57
boost::shared_ptr< SessionPlaylists > playlists
Definition: session.h:907
virtual void process_output_buffers(BufferSet &bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, int declick, bool gain_automation_ok)
Definition: route.cc:457
boost::shared_ptr< MuteMaster > _mute_master
Definition: route.h:555
int export_stuff(BufferSet &bufs, framepos_t start_frame, framecnt_t end_frame, boost::shared_ptr< Processor > endpoint, bool include_endpoint, bool for_export, bool for_freeze)
Definition: midi_track.cc:575
InstrumentInfo & instrument_info()
Definition: route.h:440
iterator begin()
Definition: midi_buffer.h:127
XMLNode & state(bool full)
Definition: midi_track.cc:216
Glib::Threads::RWLock _processor_lock
Definition: route.h:518
const uint8_t * buffer() const
Definition: Event.hpp:135
ChannelMode get_playback_channel_mode() const
Definition: midi_track.h:117
framepos_t start() const
Definition: region.h:113
MidiChannelFilter _playback_filter
Definition: midi_track.h:148
boost::shared_ptr< Diskstream > _diskstream
Definition: track.h:174
void track_input_active(IOChange, void *)
Definition: midi_track.cc:853
AutomationType midi_parameter_type(uint8_t status)
uint8_t channel() const
Definition: Parameter.hpp:48
virtual void set_diskstream(boost::shared_ptr< Diskstream >)
Definition: track.cc:554
#define MIDI_CTL_ALL_NOTES_OFF
Definition: midi_events.h:100
void require_resolve()
Definition: midi_port.cc:274
XMLNodeList::const_iterator XMLNodeConstIterator
Definition: xml++.h:49
void fill_buffers_with_input(BufferSet &bufs, boost::shared_ptr< IO > io, pframes_t nframes)
Definition: route.cc:4629
boost::shared_ptr< Playlist > playlist()
Definition: diskstream.h:127
ChanCount n_process_buffers()
Definition: route.cc:714
void push_midi_input_to_step_edit_ringbuffer(framecnt_t nframes)
Definition: midi_track.cc:521
bool input_active() const
Definition: midi_port.h:51
boost::shared_ptr< MidiPlaylist > midi_playlist()
Definition: midi_track.cc:808
Definition: ardour.h:41
bool set_channel_mode(ChannelMode mode, uint16_t mask)
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
void midi_panic(void)
Definition: midi_track.cc:651
AutoState
Definition: types.h:145