Ardour  9.0-pre0-2183-g152e0c2beb
triggerbox.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2021 Paul Davis <paul@linuxaudiosystems.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #pragma once
20 
21 #include <pthread.h>
22 
23 #include <atomic>
24 #include <map>
25 #include <memory>
26 #include <vector>
27 #include <string>
28 #include <exception>
29 
30 #include <glibmm/threads.h>
31 
32 #include "pbd/crossthread.h"
33 #include "pbd/pcg_rand.h"
34 #include "pbd/pool.h"
35 #include "pbd/properties.h"
36 #include "pbd/ringbuffer.h"
37 #include "pbd/stateful.h"
38 
39 #include "midi++/types.h"
40 
41 #include "temporal/beats.h"
42 #include "temporal/bbt_time.h"
43 #include "temporal/tempo.h"
44 
45 #include "evoral/PatchChange.h"
46 #include "evoral/SMF.h"
47 
49 #include "ardour/midi_model.h"
51 #include "ardour/processor.h"
52 #include "ardour/rt_midibuffer.h"
54 #include "ardour/types.h"
55 #include "ardour/types_convert.h"
56 
58 
59 class XMLNode;
60 
61 namespace RubberBand {
62  class RubberBandStretcher;
63 }
64 
65 namespace MIDI {
66  class Parser;
67 }
68 
69 namespace ARDOUR {
70 
71 class Session;
72 class AudioRegion;
73 class MidiRegion;
74 class TriggerBox;
75 struct SlotArmInfo;
76 class SideChain;
77 class MidiPort;
78 
79 typedef uint32_t color_t;
80 
81 LIBARDOUR_API std::string cue_marker_name (int32_t);
82 
83 class Trigger;
84 
85 typedef std::shared_ptr<Trigger> TriggerPtr;
87 
89  public:
90  enum State {
91  /* This is the initial state for a Trigger, and means that it is not
92  * doing anything at all
93  */
95  /* A Trigger in this state has been chosen by its parent TriggerBox
96  * (e.g. because of a bang() call that put it in the queue), a Trigger in
97  * this state is waiting for the next occurence of its quantization to
98  * occur before transitioning to Running
99  */
101  /* a Trigger in this state is going to deliver data during calls
102  * to its ::run() method.
103  */
105  /* a Trigger in this state was running, has been re-triggered e.g. by a
106  * ::bang() call with LaunchStyle set to Repeat, and is waiting for the
107  * next occurence of its quantization to occur before transitioning
108  * back to Running.
109  */
111  /* a Trigger in this state is delivering data during calls to ::run(), but
112  * is waiting for the next occurence of its quantization to occur when it will
113  * transition to Stopping and then Stopped.
114  */
116  /* a Trigger in this state is delivering data during calls to ::run(), but
117  * is waiting for the next occurence of another Trigger's quantization to occur when it will
118  * transition to Stopping and then Stopped (and be followed by
119  * the other Trigger.
120  */
122  /* a Trigger in this state was Running but noticed that it should stop
123  * during the current call to ::run(). By the end of that call, it will
124  * have transitioned to Stopped.
125  */
127  };
128 
129  enum LaunchStyle {
130  OneShot, /* mouse down/NoteOn starts; mouse up/NoteOff ignored */
131  ReTrigger, /* mouse down/NoteOn starts or retriggers; mouse up/NoteOff */
132  Gate, /* runs till mouse up/note off then to next quantization */
133  Toggle, /* runs till next mouse down/NoteOn */
134  Repeat, /* plays only quantization extent until mouse up/note off */
135  };
136 
137  enum StretchMode { /* currently mapped to the matching RubberBand::RubberBandStretcher::Option */
141  };
142 
143  Trigger (uint32_t index, TriggerBox&);
144  virtual ~Trigger() {}
145 
146  static void make_property_quarks ();
147 
148  protected:
149  /* properties controllable by the user */
150 
166 
167  /* Properties that are not CAS-updated at retrigger */
168 
171 
172  public:
173  /* this is positioned here so that we can easily keep it in sync
174  with the properties list above.
175  */
176  struct UIState {
177  std::atomic<unsigned int> generation; /* used for CAS */
178 
183  uint32_t follow_count = 1;
186  bool use_follow_length = false;
187  bool legato = false;
188  gain_t gain = 1.0;
189  float velocity_effect = 0;
190  bool stretchable = true;
191  bool cue_isolated = false;
192  bool allow_patch_changes = true;
194 
197 
198  std::string name = "";
199  color_t color = 0xBEBEBEFF;
200  double tempo = 0; //unset
201 
202  UIState() : generation (0) {}
203 
204  UIState& operator= (UIState const & other) {
205 
206  /* we do not copy generation */
207 
208  generation = 0;
209 
210  launch_style = other.launch_style;
214  follow_count = other.follow_count;
215  quantization = other.quantization;
218  legato = other.legato;
219  gain = other.gain;
221  stretchable = other.stretchable;
222  cue_isolated = other.cue_isolated;
224  stretch_mode = other.stretch_mode;
226 
227  for (int i = 0; i<16; i++) {
228  if (other.patch_change[i].is_set()) {
229  patch_change[i] = other.patch_change[i];
230  }
231  }
232 
233  name = other.name;
234  color = other.color;
235  tempo = other.tempo;
236 
237  return *this;
238  }
239  };
240 
241 #define TRIGGERBOX_PROPERTY_DECL(name,type) void set_ ## name (type); type name () const;
242 #define TRIGGERBOX_PROPERTY_DECL_CONST_REF(name,type) void set_ ## name (type const &); type name () const
243 
261 
262 #undef TRIGGERBOX_PROPERTY_DECL
263 #undef TRIGGERBOX_PROPERTY_DECL_CONST_REF
264 
265  /* Calling ::bang() will cause this Trigger to be placed in its owning
266  TriggerBox's queue.
267  */
268  void bang (float velocity = 1.0f);
269 
270  /* Calling ::unbang() is equivalent to a mouse-up or note-off
271  ... it MIGHT cause a clip to stop, but more likely has no effect, depending on the slot's launch-style.
272  */
273  void unbang ();
274 
275  /* Calling ::request_stop() to stop a Trigger at the earliest possible
276  * opportunity, rather than at the next quantization point.
277  */
278  void request_stop ();
279 
280  /* Call ::stop_quantized() to stop a Trigger at the next quantization point.
281  */
282  void stop_quantized ();
283 
284  virtual void tempo_map_changed() {}
285 
286  virtual pframes_t run (BufferSet&, samplepos_t start_sample, samplepos_t end_sample,
287  Temporal::Beats const & start, Temporal::Beats const & end,
288  pframes_t nframes, pframes_t offset, double bpm, pframes_t& quantize_offset) = 0;
289  virtual void set_start (timepos_t const &) = 0;
290  virtual void set_end (timepos_t const &) = 0;
291  virtual void set_length (timecnt_t const &) = 0;
292  virtual void reload (BufferSet&, void*) = 0;
293  virtual void io_change () {}
294  virtual void set_legato_offset (timepos_t const & offset) = 0;
295 
297  double position_as_fraction() const;
298 
299  virtual void captured (SlotArmInfo&) {}
301  _arm (duration);
302  }
303  virtual void disarm ();
304  bool armed() const { return _armed; }
306  static PBD::Signal<void(Trigger const *)> TriggerArmChanged;
307 
310  virtual void start_and_roll_to (samplepos_t start, samplepos_t position, uint32_t cnt) = 0;
311 
312  /* because follow actions involve probability is it easier to code the will-not-follow case */
313 
314  bool will_not_follow() const;
315  bool will_follow() const { return !will_not_follow(); }
316 
317  /* assumes that this is currently playing but does not enforce it */
318  bool cue_launched() const { return _cue_launched; }
319 
320  virtual bool probably_oneshot () const = 0;
321 
322  virtual timepos_t start_offset () const = 0; /* offset from start of data */
323  virtual timepos_t current_length() const = 0; /* offset from start() */
324  virtual timepos_t natural_length() const = 0; /* offset from start() */
325 
326  void process_state_requests (BufferSet& bufs, pframes_t dest_offset);
327 
328  bool active() const { return _state >= Running; }
329  State state() const { return _state; }
330 
331  void set_region (std::shared_ptr<Region>, bool use_thread = true);
332  void clear_region ();
333  virtual int set_region_in_worker_thread (std::shared_ptr<Region>) = 0;
334  virtual int set_region_in_worker_thread_from_capture (std::shared_ptr<Region>) = 0;
335  std::shared_ptr<Region> the_region() const { return _region; }
336  virtual bool playable() const = 0;
337 
338  uint32_t index() const { return _index; }
339 
340  /* Managed by TriggerBox, these record the time that the trigger is
341  * scheduled to start or stop at. Computed in
342  * Trigger::maybe_compute_next_transition().
343  */
347 
348  XMLNode& get_state () const;
349  int set_state (const XMLNode&, int version);
350 
351  void maybe_compute_next_transition (samplepos_t start_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t& nframes, pframes_t& dest_offset);
352 
353 
355  Temporal::BBT_Argument& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
356  Temporal::TempoMap::SharedPtr const & tmap, Temporal::BBT_Offset const & q);
357 
359  Temporal::BBT_Argument& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
360  Temporal::TempoMap::SharedPtr const & tmap);
361 
362 
363  template<typename TriggerType>
364  void start_and_roll_to (samplepos_t start_pos, samplepos_t end_position, TriggerType& trigger,
365  pframes_t (TriggerType::*run_method) (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
366  Temporal::Beats const & start_beats, Temporal::Beats const & end_beats,
367  pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t&), uint32_t cnt);
368  void set_next_trigger (int n);
369  int next_trigger() const { return _next_trigger; }
370 
371  /* any non-zero value will work for the default argument, and means
372  "use your own launch quantization". BBT_Offset (0, 0, 0) means what
373  it says: start immediately
374  */
375  void startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const & start_quantization = Temporal::BBT_Offset (9, 3,0));
376  void startup_from_ffwd (BufferSet&, uint32_t loop_cnt);
378  virtual void shutdown (BufferSet& bufs, pframes_t dest_offset);
379  virtual void jump_start ();
380  virtual void jump_stop (BufferSet& bufs, pframes_t dest_offset);
381  void begin_stop (bool explicit_stop = false);
383 
384  bool explicitly_stopped() const { return _explicitly_stopped; }
385 
386  uint32_t loop_count() const { return _loop_cnt; }
387 
388  void set_ui (void*);
389  void* ui () const { return _ui; }
390 
391  TriggerBox& box() const { return _box; }
392  std::shared_ptr<TriggerBox> boxptr() const;
393 
394  double estimated_tempo() const { return _estimated_tempo; }
395 
396  /* the following functions deal with audio- or midi-specific SegmentDescriptor properties, provided as virtuals so we don't have to do lots of dynamic_casting */
397  /* segment_tempo is currently a no-op for MIDI, but may be implemented later */
398  virtual double segment_tempo() const = 0;
399  virtual void set_segment_tempo (double t) = 0;
400 
401  /* used_channels is a no-op for audio */
404 
405  /* patch changes are a no-op for audio */
408  virtual void unset_patch_change (uint8_t channel) {}
409  virtual void unset_all_patch_changes () {}
410  virtual bool patch_change_set (uint8_t channel) const { return false; }
411 
412  virtual void setup_stretcher () = 0;
413 
414  Temporal::Meter meter() const { return _meter; }
415 
416  void set_velocity_gain (gain_t g) {_pending_velocity_gain=g;}
417 
420 
422 
424 
426 
427  static void request_trigger_delete (Trigger* t);
428 
429  /* these operations are provided to get/set all the "user visible" trigger properties at once */
430  /* examples: drag+dropping from slot to slot, or "Range->Bounce to Slot", where a single operation sets many */
431  void get_ui_state (UIState &state) const;
432  void set_ui_state (UIState &state);
433 
434  virtual void check_edit_swap (timepos_t const & time, bool playing, BufferSet& bufs) = 0;
435 
437 
439  virtual void bounds_changed (Temporal::timepos_t const & start, Temporal::timepos_t const & end, Temporal::timecnt_t const & len);
440 
441  protected:
442  struct UIRequests {
443  std::atomic<bool> stop;
444  UIRequests() : stop (false) {}
445  };
446 
447  std::shared_ptr<Region> _region;
449  samplepos_t final_processed_sample; /* where we stop playing, in process time, compare with process_index */
454  bool _playout;
455  std::atomic<int> _bang;
456  std::atomic<int> _unbang;
457  uint32_t _index;
459  uint32_t _loop_cnt; /* how many times in a row has this played */
460  void* _ui;
465  bool _armed;
466 
467  /* these are only used by midi triggers but the ui_state API needs them */
470  std::vector<int> _channel_map;
471 
473 
474 
475  /* computed from data */
476 
477  double _estimated_tempo; //TODO: this should come from the MIDI file
478  double _segment_tempo; //TODO: this will likely get stored in the SegmentDescriptor for audio triggers
479 
480  /* basic process is :
481  1) when a file is loaded, we infer its bpm either by minibpm's estimate, a flag in the filename, metadata (TBD) or other means
482  2) we assume the clip must have an integer number of beats in it (simplest case is a one-bar loop with 4 beats in it)
483  3) ...so we round to the nearest beat length, and set the tempo to *exactly* fit the sample-length into the assumed beat-length
484  4) the user may recognize a problem: "this was a 3/4 beat, which was rounded to 4 beats but it should have been 3"
485  5) if the user changes the beat-length, then the tempo is recalculated for use during stretching
486  6) someday, we will also allow the sample start and length to be adjusted in a trimmer, and that will also adjust the tempo
487  7) in all cases the user should be in final control; but our "internal" value for stretching are just sample-start and BPM, end of story
488  */
489  double _beatcnt;
491 
495  std::atomic<Trigger*> _pending;
496  std::atomic<unsigned int> last_property_generation;
498 
499  void when_stopped_during_run (BufferSet& bufs, pframes_t dest_offset);
500  void set_region_internal (std::shared_ptr<Region>);
501  virtual void retrigger();
502  virtual void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &);
503 
506 
507  virtual void _arm (Temporal::BBT_Offset const &);
508 
509  struct PendingSwap {
515 
516  virtual ~PendingSwap() {}
517  };
518 
519  std::atomic<PendingSwap*> pending_swap;
520  std::atomic<PendingSwap*> old_pending_swap;
521 
522  virtual void adjust_bounds (Temporal::timepos_t const & start, Temporal::timepos_t const & end, Temporal::timecnt_t const & length, bool from_region) = 0;
523 };
524 
526  public:
527  AudioTrigger (uint32_t index, TriggerBox&);
529 
530  template<bool actually_run> pframes_t audio_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
531  Temporal::Beats const & start, Temporal::Beats const & end,
532  pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t& quantize_offset);
533 
534  pframes_t run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t& quantize_offset) {
535  return audio_run<true> (bufs, start_sample, end_sample, start, end, nframes, dest_offset, bpm, quantize_offset);
536  }
537 
538  bool playable() const { return data.length || _region; }
539 
540  StretchMode stretch_mode() const { return _stretch_mode; }
542 
543  double segment_tempo() const { return _segment_tempo; }
544  void set_segment_tempo (double t);
545 
546  double segment_beatcnt () { return _beatcnt; }
547  void set_segment_beatcnt (double count);
548 
549  void set_start (timepos_t const &);
550  void set_end (timepos_t const &);
551  void set_legato_offset (timepos_t const &);
552  void set_length (timecnt_t const &);
554  timepos_t start_offset () const; /* offset from start of data */
555  timepos_t current_length() const; /* offset from start of data */
556  timepos_t natural_length() const; /* offset from start of data */
557  void reload (BufferSet&, void*);
558  void io_change ();
559  bool probably_oneshot () const;
560 
562 
563  int set_region_in_worker_thread (std::shared_ptr<Region>);
564  int set_region_in_worker_thread_from_capture (std::shared_ptr<Region>);
565  void jump_start ();
566  void jump_stop (BufferSet& bufs, pframes_t dest_offset);
567 
568  XMLNode& get_state () const;
569  int set_state (const XMLNode&, int version);
570 
571  RubberBand::RubberBandStretcher* stretcher() { return (_stretcher); }
572 
576 
577  bool stretching () const;
578  uint32_t channels () const { return data.size(); }
579 
580  RubberBand::RubberBandStretcher* alloc_stretcher () const;
581 
582  struct AudioData : std::vector<Sample*> {
585 
586  AudioData () : length (0), capacity (0) {}
588 
589  samplecnt_t append (Sample const * src, samplecnt_t cnt, uint32_t chan);
590  void alloc (samplecnt_t cnt, uint32_t nchans);
591  void reset () { length = 0; }
592  };
593 
594 
595  Sample const * audio_data (size_t n) const;
596  size_t data_length() const { return data.length; }
597  samplecnt_t user_data_length() const { return _user_data_length; }
598 
599  void check_edit_swap (timepos_t const &, bool playing, BufferSet&);
600 
601  protected:
602  void retrigger ();
603  void adjust_bounds (Temporal::timepos_t const & start, Temporal::timepos_t const & end, Temporal::timecnt_t const & length, bool from_region);
604 
605  private:
608  RubberBand::RubberBandStretcher* _stretcher;
610 
611  /* computed during run */
612 
614  samplepos_t last_readable_sample; /* where the data runs out, relative to the start of the data, compare with read_index */
620 
621  virtual void setup_stretcher ();
622 
623  void drop_data ();
624  int load_data (std::shared_ptr<AudioRegion>);
625  void estimate_tempo ();
627  void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &);
628  int set_region_in_worker_thread_internal (std::shared_ptr<Region> r, bool from_capture);
629 };
630 
631 
633  public:
634  MIDITrigger (uint32_t index, TriggerBox&);
636 
637  bool playable() const { return rt_midibuffer.load() || _region; }
638 
640  void disarm ();
641 
642  template<bool actually_run> pframes_t midi_run (BufferSet&, samplepos_t start_sample, samplepos_t end_sample,
643  Temporal::Beats const & start_beats, Temporal::Beats const & end_beats, pframes_t nframes, pframes_t offset, double bpm, pframes_t& quantize_offset);
644 
645  pframes_t run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t& quantize_offset) {
646  return midi_run<true> (bufs, start_sample, end_sample, start, end, nframes, dest_offset, bpm, quantize_offset);
647  }
648 
649  void set_start (timepos_t const &);
650  void set_end (timepos_t const &);
651  void set_legato_offset (timepos_t const &);
652  void set_length (timecnt_t const &);
654  timepos_t end() const; /* offset from start of data */
655  timepos_t current_length() const; /* offset from start of data */
656  timepos_t natural_length() const; /* offset from start of data */
657  void reload (BufferSet&, void*);
658  bool probably_oneshot () const;
659 
662 
663  int set_region_in_worker_thread (std::shared_ptr<Region>);
664  int set_region_in_worker_thread_from_capture (std::shared_ptr<Region>);
665  void jump_start ();
666  void shutdown (BufferSet& bufs, pframes_t dest_offset);
667  void jump_stop (BufferSet& bufs, pframes_t dest_offset);
668 
669  XMLNode& get_state () const;
670  int set_state (const XMLNode&, int version);
671 
675 
678  void unset_patch_change (uint8_t channel);
680  bool patch_change_set (uint8_t channel) const;
681 
682  /* It's possible that a portion of a midi file would use a subset of the total channels used, so store that info in the segment descriptor */
683  Evoral::SMF::UsedChannels used_channels() const { return ui_state.used_channels; }
685 
686  /* theoretically, MIDI files can have a dedicated tempo outside the session tempo map (*un-stretched*) but this is currently unimplemented */
687  /* boilerplate tempo functions are provided here so we don't have to do constant dynamic_cast checks to use the tempo+stretch APIs */
688  virtual double segment_tempo() const {return 120.0;}
689  virtual void set_segment_tempo (double t) {}
690  virtual void setup_stretcher () {}
691 
692  void set_channel_map (int channel, int target);
693  void unset_channel_map (int channel);
694  int channel_map (int channel);
695  std::vector<int> const & channel_map() const { return _channel_map; }
696 
697  void check_edit_swap (timepos_t const &, bool playing, BufferSet&);
698  RTMidiBufferBeats const & rt_midi_buffer() const { return *rt_midibuffer.load(); }
699 
700  Temporal::Beats play_start() const { return _play_start; }
701  Temporal::Beats play_end() const { return _play_end; }
702  Temporal::Beats loop_start() const { return _loop_start; }
703  Temporal::Beats loop_end() const { return _loop_end; }
704 
705  protected:
706  void retrigger ();
707  void _arm (Temporal::BBT_Offset const &);
708  void adjust_bounds (Temporal::timepos_t const & start, Temporal::timepos_t const & end, Temporal::timecnt_t const & length, bool from_region);
709 
710  private:
712 
714 
715  Temporal::DoubleableBeats data_length; /* using timestamps from data */
718 
721 
722  std::shared_ptr<MidiModel> _model;
725 
732 
733  std::atomic<RTMidiBufferBeats*> rt_midibuffer;
734  uint32_t iter; /* index into the above RTMidiBufferBeats for current playback */
735 
736  struct MIDIPendingSwap : public PendingSwap {
738 
739  MIDIPendingSwap() : rt_midibuffer (nullptr) {}
740  ~MIDIPendingSwap() { delete rt_midibuffer; }
741  };
742 
744 
745  int load_data (std::shared_ptr<MidiRegion>);
747  void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &);
749 };
750 
752 {
753  public:
756 
757  static void init_request_pool() { Request::init_pool(); }
758 
759  void set_region (TriggerBox&, uint32_t slot, std::shared_ptr<Region>);
762 
763  void summon();
764  void stop();
766 
767  private:
768  static void* _thread_work(void *arg);
769  void* thread_work();
770 
771  enum RequestType {
775  BuildSourceAndRegion
776  };
777 
778  struct Request {
779 
780  Request (RequestType t) : type (t) {}
781 
783  /* for set region */
785  uint32_t slot;
786  std::shared_ptr<Region> region;
787  /* for DeleteTrigger and BuildSourceAndRegion */
791 
792  void* operator new (size_t);
793  void operator delete (void* ptr, size_t);
794 
796  static void init_pool ();
797  };
798 
799  pthread_t thread;
801 
805  void build_source (Trigger*, Temporal::timecnt_t const & duration, Temporal::timepos_t const &);
808 };
809 
810 struct CueRecord {
811  int32_t cue_number;
813 
814  CueRecord (int32_t cn, samplepos_t t): cue_number (cn), when (t) {}
815  CueRecord () : cue_number (0), when (0) {}
816 
817  static const int32_t stop_all = INT32_MAX;
818 };
819 
821 
822 struct SlotArmInfo {
825 
826  void reset (Trigger&);
827 
836  RubberBand::RubberBandStretcher* stretcher;
837 };
838 
839 class LIBARDOUR_API TriggerBox : public Processor, public std::enable_shared_from_this<TriggerBox>
840 {
841  public:
842 
843 #ifdef MIXBUS
844  static const int32_t default_triggers_per_box = 8;
845 #else
846  static const int32_t default_triggers_per_box = 16;
847 #endif
848 
851 
853  static bool cue_recording () { return _cue_recording; }
854  static void set_cue_recording (bool yn);
856 
857  void set_record_enabled (bool yn);
858  RecordState record_enabled() const { return _record_state; }
861  static PBD::Signal<void(Trigger const *)> RegionCaptured;
862 
863  void arm_from_another_thread (Trigger& slot, samplepos_t, uint32_t chans, Temporal::BBT_Offset const &);
864  void disarm();
865  void disarm_all();
866  bool armed() const { return (bool) _arm_info.load(); }
868 
869  void run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool result_required);
870  void run_cycle (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes);
873 
874  bool empty() const { return _active_slots == 0; }
876 
877  int32_t order() const { return _order; }
878  void set_order(int32_t n);
879 
880  typedef std::vector<TriggerPtr> Triggers;
881 
882  TriggerPtr trigger (Triggers::size_type);
883 
884  void bang_trigger_at (Triggers::size_type row, float velocity = 1.0f);
885  void unbang_trigger_at (Triggers::size_type row);
886 
888 
889  void fast_forward (CueEvents const &, samplepos_t transport_position);
890  bool fast_forwarding() const { return _fast_forwarding; }
891 
892  void set_pending (uint32_t slot, Trigger*);
893 
894  XMLNode& get_state () const;
895  int set_state (const XMLNode&, int version);
896 
897  void deep_sources (std::set<std::shared_ptr<Source>>&);
898  void used_regions (std::set<std::shared_ptr<Region>>&);
899 
900  void set_from_path (uint32_t slot, std::string const & path);
901  void set_from_selection (uint32_t slot, std::shared_ptr<Region>);
902 
903  DataType data_type() const { return _data_type; }
904 
907 
908  TriggerPtr currently_playing() const { return _currently_playing; }
909 
911 
913  void clear_cue (int cue);
914  void set_all_follow_action (ARDOUR::FollowAction const &, uint32_t n=0);
917  void set_all_probability (int zero_to_a_hundred);
918 
919  /* Returns a negative value is there is no active Trigger, or a value between 0
920  * and 1.0 if there is, corresponding to the value of position_as_fraction() for
921  * the active Trigger.
922  */
923  double position_as_fraction() const;
924 
925  void queue_explict (uint32_t);
928 
929  void request_reload (int32_t slot, void*);
930  void set_region (uint32_t slot, std::shared_ptr<Region> region);
931 
935 
936  void enqueue_trigger_state_for_region (std::shared_ptr<Region>, std::shared_ptr<Trigger::UIState>);
937 
939 
940  /* valid only within the ::run() call tree */
941  int32_t active_scene() const { return _active_scene; }
942 
943  PBD::Signal<void(uint32_t)> TriggerSwapped;
944 
950  };
951 
952  /* This is null for TriggerBoxen constructed with DataType::AUDIO */
954 
955  static bool lookup_custom_midi_binding (std::vector<uint8_t> const &, int& x, int& y);
956  static void add_custom_midi_binding (std::vector<uint8_t> const &, int x, int y);
957  static void remove_custom_midi_binding (int x, int y);
959  static int save_custom_midi_bindings (std::string const & path);
960  static int load_custom_midi_bindings (XMLNode const &);
962 
963  void begin_midi_learn (int index);
964  void midi_unlearn (int index);
966 
967  static Temporal::BBT_Offset assumed_trigger_duration () { return _assumed_trigger_duration; }
969 
970  static TriggerMidiMapMode midi_map_mode () { return _midi_map_mode; }
972 
973  static int first_midi_note() { return _first_midi_note; }
974  static void set_first_midi_note (int n);
975 
976  static void init ();
977  static void static_init (Session&);
978  static void begin_process_cycle ();
979 
981 
983 
985 
988 
989  std::shared_ptr<MidiBuffer> get_gui_feed_buffer () const;
990 
991  void dump (std::ostream &) const;
992 
994 
995  /* return start time for capture; only valid if is_set is true upon return */
996  Temporal::Beats start_time (bool& is_set) const;
997 
999 
1000  private:
1001  struct Requests {
1002  std::atomic<bool> stop_all;
1003 
1004  Requests () : stop_all (false) {}
1005  };
1006 
1008 
1010  int32_t _order;
1011  mutable Glib::Threads::RWLock trigger_lock; /* protects all_triggers */
1013 
1014  typedef std::vector<Trigger*> PendingTriggers;
1016 
1017  PBD::RingBuffer<uint32_t> explicit_queue; /* user queued triggers */
1021  int32_t _active_scene;
1022  int32_t _active_slots;
1027 
1029 
1030  void maybe_capture (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes);
1032 
1033  /* These four are accessed (read/write) only from process() context */
1034 
1035  void drop_triggers ();
1038  int determine_next_trigger (uint32_t n);
1039  void stop_all ();
1040 
1041  void maybe_swap_pending (uint32_t);
1042 
1043  void parameter_changed (std::string const &);
1044  static void static_parameter_changed (std::string const &);
1045 
1046  static int _first_midi_note;
1048 
1049  struct Request {
1050  enum Type {
1053  };
1054 
1056 
1057  /* cannot use a union here because we need Request to have a
1058  * "trivial" constructor.
1059  */
1060 
1062  void* ptr;
1063  int32_t slot;
1064 
1065  Request (Type t) : type (t) {}
1066 
1068  static void init_pool();
1069 
1070  void* operator new (size_t);
1071  void operator delete (void* ptr, size_t);
1072  };
1073 
1076 
1079 
1080  void reload (BufferSet& bufs, int32_t slot, void* ptr);
1081 
1084  int handle_stopped_trigger (BufferSet& bufs, pframes_t dest_offset);
1085 
1087  std::atomic<SlotArmInfo*> _arm_info;
1089 
1094  mutable Glib::Threads::Mutex _gui_feed_reset_mutex;
1095 
1096  typedef std::map<std::vector<uint8_t>,std::pair<int,int> > CustomMidiMap;
1098 
1100  static std::shared_ptr<MIDI::Parser> input_parser;
1102  static void input_port_check ();
1104  static std::shared_ptr<MidiPort> current_input;
1105 
1106  static bool _learning;
1107  static std::pair<int,int> learning_for;
1109 
1110  static void init_pool();
1111 
1112  static std::atomic<int> active_trigger_boxes;
1113  static std::atomic<bool> _cue_recording;
1114  static bool roll_requested;
1115  static void maybe_request_roll (Session&);
1116 };
1117 
1119 {
1120  public:
1122  TriggerReference (std::shared_ptr<ARDOUR::TriggerBox> b, uint32_t s) : weak_box (b), _slot (s) {}
1123 
1124  std::shared_ptr<ARDOUR::Trigger> trigger() const { std::shared_ptr<ARDOUR::TriggerBox> box (weak_box.lock()); return box ? box->trigger (_slot) : std::shared_ptr<ARDOUR::Trigger>(); }
1125  void set (std::shared_ptr<ARDOUR::TriggerBox> b, uint32_t s) { weak_box = b; _slot = s; }
1126  uint32_t slot() const { return _slot; }
1127  std::shared_ptr<ARDOUR::TriggerBox> box() const { return weak_box.lock(); }
1128 
1129  bool operator== (TriggerReference const & other) {
1130  return _slot == other._slot && box() == other.box();
1131  }
1132 
1133  private:
1134  std::weak_ptr<ARDOUR::TriggerBox> weak_box;
1135  uint32_t _slot;
1136 };
1137 
1138 namespace Properties {
1157  LIBARDOUR_API extern PBD::PropertyDescriptor<bool> patch_change; /* type not important */
1158  LIBARDOUR_API extern PBD::PropertyDescriptor<bool> channel_map; /* type not important */
1159  LIBARDOUR_API extern PBD::PropertyDescriptor<bool> used_channels; /* type not important */
1160  LIBARDOUR_API extern PBD::PropertyDescriptor<bool> region; /* type not important */
1161 
1162  LIBARDOUR_API extern PBD::PropertyDescriptor<bool> tempo_meter; /* only used to transmit changes, not storage */
1163 }
1164 
1165 
1166 } // namespace ARDOUR
1167 
1168 namespace PBD {
1172 } /* namespace PBD */
samplecnt_t to_pad
Definition: triggerbox.h:618
RubberBand::RubberBandStretcher * _stretcher
Definition: triggerbox.h:608
samplepos_t _legato_offset
Definition: triggerbox.h:615
bool stretching() const
int set_region_in_worker_thread_from_capture(std::shared_ptr< Region >)
samplecnt_t user_data_length() const
Definition: triggerbox.h:597
SegmentDescriptor get_segment_descriptor() const
RubberBand::RubberBandStretcher * alloc_stretcher() const
samplepos_t last_readable_sample
Definition: triggerbox.h:614
void set_segment_tempo(double t)
void set_end(timepos_t const &)
void adjust_bounds(Temporal::timepos_t const &start, Temporal::timepos_t const &end, Temporal::timecnt_t const &length, bool from_region)
timepos_t current_length() const
void set_start(timepos_t const &)
timepos_t compute_end(Temporal::TempoMap::SharedPtr const &, Temporal::BBT_Time const &, samplepos_t, Temporal::Beats &)
void captured(SlotArmInfo &)
timepos_t natural_length() const
samplecnt_t read_index
Definition: triggerbox.h:613
samplecnt_t to_drop
Definition: triggerbox.h:619
XMLNode & get_state() const
void reload(BufferSet &, void *)
uint32_t channels() const
Definition: triggerbox.h:578
AudioTrigger(uint32_t index, TriggerBox &)
double segment_tempo() const
Definition: triggerbox.h:543
void set_user_data_length(samplecnt_t)
RubberBand::RubberBandStretcher * stretcher()
Definition: triggerbox.h:571
void set_length(timecnt_t const &)
size_t data_length() const
Definition: triggerbox.h:596
int set_state(const XMLNode &, int version)
int set_region_in_worker_thread(std::shared_ptr< Region >)
double segment_beatcnt()
Definition: triggerbox.h:546
virtual void setup_stretcher()
samplepos_t _start_offset
Definition: triggerbox.h:609
void _startup(BufferSet &, pframes_t dest_offset, Temporal::BBT_Offset const &)
int set_region_in_worker_thread_internal(std::shared_ptr< Region > r, bool from_capture)
void set_legato_offset(timepos_t const &)
void set_segment_beatcnt(double count)
StretchMode stretch_mode() const
Definition: triggerbox.h:540
int load_data(std::shared_ptr< AudioRegion >)
void set_stretch_mode(StretchMode)
samplecnt_t retrieved
Definition: triggerbox.h:616
samplecnt_t got_stretcher_padding
Definition: triggerbox.h:617
bool probably_oneshot() const
samplecnt_t _user_data_length
Definition: triggerbox.h:607
bool playable() const
Definition: triggerbox.h:538
timepos_t start_offset() const
void check_edit_swap(timepos_t const &, bool playing, BufferSet &)
pframes_t audio_run(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const &start, Temporal::Beats const &end, pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t &quantize_offset)
Sample const * audio_data(size_t n) const
pframes_t run(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const &start, Temporal::Beats const &end, pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t &quantize_offset)
Definition: triggerbox.h:534
void start_and_roll_to(samplepos_t start, samplepos_t position, uint32_t cnt)
void jump_stop(BufferSet &bufs, pframes_t dest_offset)
RTMidiBufferBeats const & rt_midi_buffer() const
Definition: triggerbox.h:698
void captured(SlotArmInfo &)
void set_legato_offset(timepos_t const &)
samplepos_t last_event_samples
Definition: triggerbox.h:717
void check_edit_swap(timepos_t const &, bool playing, BufferSet &)
void shutdown(BufferSet &bufs, pframes_t dest_offset)
Temporal::Beats play_start() const
Definition: triggerbox.h:700
Temporal::Beats loop_start() const
Definition: triggerbox.h:702
uint32_t last_event_index
Definition: triggerbox.h:731
timepos_t current_length() const
void _startup(BufferSet &, pframes_t dest_offset, Temporal::BBT_Offset const &)
XMLNode & get_state() const
Temporal::Beats _play_start
Definition: triggerbox.h:726
void set_used_channels(Evoral::SMF::UsedChannels)
void compute_and_set_length()
void estimate_midi_patches()
Temporal::Beats _loop_end
Definition: triggerbox.h:729
void reload(BufferSet &, void *)
void _arm(Temporal::BBT_Offset const &)
virtual double segment_tempo() const
Definition: triggerbox.h:688
Temporal::DoubleableBeats last_event_beats
Definition: triggerbox.h:716
Temporal::Beats _loop_start
Definition: triggerbox.h:728
void unset_all_patch_changes()
timepos_t compute_end(Temporal::TempoMap::SharedPtr const &, Temporal::BBT_Time const &, samplepos_t, Temporal::Beats &)
bool patch_change_set(uint8_t channel) const
void unset_channel_map(int channel)
timepos_t natural_length() const
Temporal::Beats final_beat
Definition: triggerbox.h:713
Temporal::Beats _play_end
Definition: triggerbox.h:727
pframes_t midi_run(BufferSet &, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const &start_beats, Temporal::Beats const &end_beats, pframes_t nframes, pframes_t offset, double bpm, pframes_t &quantize_offset)
void unset_patch_change(uint8_t channel)
void set_patch_change(Evoral::PatchChange< MidiBuffer::TimeType > const &)
int set_state(const XMLNode &, int version)
MIDITrigger(uint32_t index, TriggerBox &)
pframes_t run(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const &start, Temporal::Beats const &end, pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t &quantize_offset)
Definition: triggerbox.h:645
bool playable() const
Definition: triggerbox.h:637
timepos_t end() const
std::vector< int > const & channel_map() const
Definition: triggerbox.h:695
std::shared_ptr< MidiModel > _model
Definition: triggerbox.h:722
Evoral::SMF::UsedChannels used_channels() const
Definition: triggerbox.h:683
bool probably_oneshot() const
uint32_t first_event_index
Definition: triggerbox.h:730
Temporal::Beats play_end() const
Definition: triggerbox.h:701
Temporal::Beats loop_end() const
Definition: triggerbox.h:703
virtual void setup_stretcher()
Definition: triggerbox.h:690
Temporal::BBT_Offset _legato_offset
Definition: triggerbox.h:720
void set_length(timecnt_t const &)
void jump_stop(BufferSet &bufs, pframes_t dest_offset)
void model_contents_changed()
virtual void set_segment_tempo(double t)
Definition: triggerbox.h:689
int channel_map(int channel)
SegmentDescriptor get_segment_descriptor() const
void set_channel_map(int channel, int target)
std::atomic< RTMidiBufferBeats * > rt_midibuffer
Definition: triggerbox.h:733
void adjust_bounds(Temporal::timepos_t const &start, Temporal::timepos_t const &end, Temporal::timecnt_t const &length, bool from_region)
Evoral::PatchChange< MidiBuffer::TimeType > const patch_change(uint8_t) const
void set_start(timepos_t const &)
int set_region_in_worker_thread(std::shared_ptr< Region >)
timepos_t start_offset() const
PBD::ScopedConnection content_connection
Definition: triggerbox.h:723
int load_data(std::shared_ptr< MidiRegion >)
Temporal::DoubleableBeats data_length
Definition: triggerbox.h:715
void start_and_roll_to(samplepos_t start, samplepos_t position, uint32_t cnt)
void set_end(timepos_t const &)
Temporal::BBT_Offset _start_offset
Definition: triggerbox.h:719
int set_region_in_worker_thread_from_capture(std::shared_ptr< Region >)
CrossThreadChannel _xthread
Definition: triggerbox.h:802
void build_audio_source(AudioTrigger *, Temporal::timecnt_t const &, Temporal::timepos_t const &)
void build_midi_source(MIDITrigger *, Temporal::timecnt_t const &, Temporal::timepos_t const &)
void set_region(TriggerBox &, uint32_t slot, std::shared_ptr< Region >)
void build_source(Trigger *, Temporal::timecnt_t const &duration, Temporal::timepos_t const &)
void request_build_source(Trigger *t, Temporal::timecnt_t const &duration, Temporal::timepos_t const &)
void queue_request(Request *)
static void init_request_pool()
Definition: triggerbox.h:757
void delete_trigger(Trigger *)
void request_delete_trigger(Trigger *t)
PBD::RingBuffer< Request * > requests
Definition: triggerbox.h:800
static void * _thread_work(void *arg)
static TriggerBoxThread * worker
Definition: triggerbox.h:980
static void static_parameter_changed(std::string const &)
void used_regions(std::set< std::shared_ptr< Region >> &)
int32_t active_scene() const
Definition: triggerbox.h:941
static TriggerMidiMapMode _midi_map_mode
Definition: triggerbox.h:1047
static void init()
static PBD::Signal< void()> TriggerRecEnableChanged
Definition: triggerbox.h:860
static PBD::ScopedConnectionList static_connections
Definition: triggerbox.h:1103
void process_ui_trigger_requests()
TriggerBox(Session &, DataType dt)
double position_as_fraction() const
void set_record_enabled(bool yn)
void process_request(BufferSet &, Request *)
bool configure_io(ChanCount in, ChanCount out)
PendingTriggers pending
Definition: triggerbox.h:1015
EventRingBuffer< samplepos_t > _gui_feed_fifo
Definition: triggerbox.h:1093
RequestBuffer requests
Definition: triggerbox.h:1075
PBD::ScopedConnection stop_all_connection
Definition: triggerbox.h:1086
void fast_forward_nothing_to_do()
void process_requests(BufferSet &)
Temporal::Beats start_time(bool &is_set) const
TriggerPtr get_next_trigger()
static PBD::Signal< void(PBD::PropertyChange, int)> TriggerBoxPropertyChange
Definition: triggerbox.h:987
static void static_init(Session &)
void maybe_swap_pending(uint32_t)
Triggers all_triggers
Definition: triggerbox.h:1012
void set_all_quantization(Temporal::BBT_Offset const &)
void set_armed(SlotArmInfo *)
static TriggerMidiMapMode midi_map_mode()
Definition: triggerbox.h:970
void deep_sources(std::set< std::shared_ptr< Source >> &)
void cancel_locate_armed()
int set_state(const XMLNode &, int version)
static void maybe_request_roll(Session &)
void set_from_selection(uint32_t slot, std::shared_ptr< Region >)
XMLNode & get_state() const
PBD::Signal< void(uint32_t)> TriggerSwapped
Definition: triggerbox.h:943
int handle_stopped_trigger(BufferSet &bufs, pframes_t dest_offset)
static void set_first_midi_note(int n)
static void add_custom_midi_binding(std::vector< uint8_t > const &, int x, int y)
void dump(std::ostream &) const
static bool _learning
Definition: triggerbox.h:1106
TriggerPtr trigger(Triggers::size_type)
int32_t order() const
Definition: triggerbox.h:877
static void init_pool()
SlotArmInfo _the_arm_info
Definition: triggerbox.h:1088
static CueRecords cue_records
Definition: triggerbox.h:852
int determine_next_trigger(uint32_t n)
void non_realtime_transport_stop(samplepos_t now, bool flush)
TriggerPtr peek_next_trigger()
static void midi_input_handler(MIDI::Parser &, MIDI::byte *, size_t, samplecnt_t)
static void set_midi_map_mode(TriggerMidiMapMode m)
static PBD::ScopedConnection midi_input_connection
Definition: triggerbox.h:1101
DataType data_type() const
Definition: triggerbox.h:903
void begin_midi_learn(int index)
static void clear_custom_midi_bindings()
PBD::Signal< void(samplecnt_t)> Captured
Definition: triggerbox.h:993
static std::pair< int, int > learning_for
Definition: triggerbox.h:1107
PBD::RingBuffer< Request * > RequestBuffer
Definition: triggerbox.h:1074
bool armed() const
Definition: triggerbox.h:866
static Temporal::BBT_Offset assumed_trigger_duration()
Definition: triggerbox.h:967
void midi_unlearn(int index)
static void begin_process_cycle()
bool can_support_io_configuration(const ChanCount &in, ChanCount &out)
void non_realtime_locate(samplepos_t now)
void set_all_launch_style(ARDOUR::Trigger::LaunchStyle)
static bool lookup_custom_midi_binding(std::vector< uint8_t > const &, int &x, int &y)
static std::atomic< int > active_trigger_boxes
Definition: triggerbox.h:1112
static void set_cue_recording(bool yn)
void fast_forward(CueEvents const &, samplepos_t transport_position)
void set_all_follow_action(ARDOUR::FollowAction const &, uint32_t n=0)
std::map< std::vector< uint8_t >, std::pair< int, int > > CustomMidiMap
Definition: triggerbox.h:1096
static std::shared_ptr< MidiPort > current_input
Definition: triggerbox.h:1104
void set_pending(uint32_t slot, Trigger *)
static int first_midi_note()
Definition: triggerbox.h:973
static CustomMidiMap _custom_midi_map
Definition: triggerbox.h:1097
void set_order(int32_t n)
PBD::Signal< void()> ArmedChanged
Definition: triggerbox.h:867
void clear_cue(int cue)
static PBD::Signal< void(Trigger const *)> RegionCaptured
Definition: triggerbox.h:861
void maybe_capture(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes)
PBD::Signal< void()> EmptyStatusChanged
Definition: triggerbox.h:875
void parameter_changed(std::string const &)
void request_reload(int32_t slot, void *)
static Temporal::BBT_Offset _assumed_trigger_duration
Definition: triggerbox.h:1007
void bang_trigger_at(Triggers::size_type row, float velocity=1.0f)
PBD::Signal< void()> RecEnableChanged
Definition: triggerbox.h:859
static void remove_custom_midi_binding(int x, int y)
static bool roll_requested
Definition: triggerbox.h:1114
std::vector< Trigger * > PendingTriggers
Definition: triggerbox.h:1014
RecordState _record_state
Definition: triggerbox.h:1026
std::shared_ptr< MidiBuffer > get_gui_feed_buffer() const
static int save_custom_midi_bindings(std::string const &path)
PBD::PCGRand _pcg
Definition: triggerbox.h:1028
std::vector< TriggerPtr > Triggers
Definition: triggerbox.h:880
PBD::RingBuffer< uint32_t > explicit_queue
Definition: triggerbox.h:1017
void arm_from_another_thread(Trigger &slot, samplepos_t, uint32_t chans, Temporal::BBT_Offset const &)
static PBD::Signal< void()> TriggerMIDILearned
Definition: triggerbox.h:1108
void queue_explict(uint32_t)
static std::atomic< bool > _cue_recording
Definition: triggerbox.h:1113
static void set_assumed_trigger_duration(Temporal::BBT_Offset const &)
void reload(BufferSet &bufs, int32_t slot, void *ptr)
void realtime_handle_transport_stopped()
void unbang_trigger_at(Triggers::size_type row)
static PBD::PropertyChange all_trigger_props()
void process_midi_trigger_requests(BufferSet &)
static void start_transport_stop(Session &)
bool fast_forwarding() const
Definition: triggerbox.h:890
static XMLNode * get_custom_midi_binding_state()
bool empty() const
Definition: triggerbox.h:874
TriggerPtr currently_playing() const
Definition: triggerbox.h:908
static int load_custom_midi_bindings(XMLNode const &)
void add_trigger(TriggerPtr)
void run(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool result_required)
static bool cue_recording()
Definition: triggerbox.h:853
void send_property_change(PBD::PropertyChange pc)
void enqueue_trigger_state_for_region(std::shared_ptr< Region >, std::shared_ptr< Trigger::UIState >)
Glib::Threads::Mutex _gui_feed_reset_mutex
Definition: triggerbox.h:1094
static PBD::Signal< void()> CueRecordingChanged
Definition: triggerbox.h:855
static int _first_midi_note
Definition: triggerbox.h:1046
void run_cycle(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes)
static void input_port_check()
void set_region(uint32_t slot, std::shared_ptr< Region > region)
void set_from_path(uint32_t slot, std::string const &path)
Glib::Threads::RWLock trigger_lock
Definition: triggerbox.h:1011
std::atomic< SlotArmInfo * > _arm_info
Definition: triggerbox.h:1087
void set_all_probability(int zero_to_a_hundred)
void stop_all_immediately()
MidiStateTracker * tracker
Definition: triggerbox.h:953
TriggerPtr trigger_by_id(PBD::ID)
static std::shared_ptr< MIDI::Parser > input_parser
Definition: triggerbox.h:1100
TriggerPtr _currently_playing
Definition: triggerbox.h:1018
RecordState record_enabled() const
Definition: triggerbox.h:858
TriggerReference(std::shared_ptr< ARDOUR::TriggerBox > b, uint32_t s)
Definition: triggerbox.h:1122
std::shared_ptr< ARDOUR::Trigger > trigger() const
Definition: triggerbox.h:1124
void set(std::shared_ptr< ARDOUR::TriggerBox > b, uint32_t s)
Definition: triggerbox.h:1125
std::shared_ptr< ARDOUR::TriggerBox > box() const
Definition: triggerbox.h:1127
std::weak_ptr< ARDOUR::TriggerBox > weak_box
Definition: triggerbox.h:1134
uint32_t slot() const
Definition: triggerbox.h:1126
bool operator==(TriggerReference const &other)
Definition: triggerbox.h:1129
std::atomic< PendingSwap * > old_pending_swap
Definition: triggerbox.h:520
uint32_t loop_count() const
Definition: triggerbox.h:386
void process_state_requests(BufferSet &bufs, pframes_t dest_offset)
double _estimated_tempo
Definition: triggerbox.h:477
Temporal::Meter meter() const
Definition: triggerbox.h:414
virtual void shutdown(BufferSet &bufs, pframes_t dest_offset)
bool will_not_follow() const
samplecnt_t process_index
Definition: triggerbox.h:448
PBD::Property< bool > _cue_isolated
Definition: triggerbox.h:163
virtual void set_patch_change(Evoral::PatchChange< MidiBuffer::TimeType > const &)
Definition: triggerbox.h:406
uint32_t _loop_cnt
Definition: triggerbox.h:459
std::vector< int > _channel_map
Definition: triggerbox.h:470
PBD::Property< LaunchStyle > _launch_style
Definition: triggerbox.h:151
virtual Evoral::SMF::UsedChannels used_channels() const
Definition: triggerbox.h:402
virtual Evoral::PatchChange< MidiBuffer::TimeType > const patch_change(uint8_t) const
Definition: triggerbox.h:407
PBD::Property< Temporal::BBT_Offset > _quantization
Definition: triggerbox.h:156
virtual timepos_t current_length() const =0
Temporal::BBT_Offset _start_quantization
Definition: triggerbox.h:493
PBD::Property< FollowAction > _follow_action0
Definition: triggerbox.h:152
bool armed() const
Definition: triggerbox.h:304
void set_ui(void *)
TriggerBox & box() const
Definition: triggerbox.h:391
pframes_t compute_next_transition(samplepos_t start_sample, Temporal::Beats const &start, Temporal::Beats const &end, pframes_t nframes, Temporal::BBT_Argument &t_bbt, Temporal::Beats &t_beats, samplepos_t &t_samples, Temporal::TempoMap::SharedPtr const &tmap)
PBD::Property< FollowAction > _follow_action1
Definition: triggerbox.h:153
std::atomic< int > _bang
Definition: triggerbox.h:455
virtual bool patch_change_set(uint8_t channel) const
Definition: triggerbox.h:410
void begin_stop(bool explicit_stop=false)
PBD::Property< float > _velocity_effect
Definition: triggerbox.h:161
Temporal::Meter _meter
Definition: triggerbox.h:490
PBD::Property< bool > _stretchable
Definition: triggerbox.h:162
samplepos_t transition_samples
Definition: triggerbox.h:344
static PBD::Signal< void(Trigger const *)> TriggerArmChanged
Definition: triggerbox.h:306
void region_property_change(PBD::PropertyChange const &)
void set_region_internal(std::shared_ptr< Region >)
double position_as_fraction() const
int next_trigger() const
Definition: triggerbox.h:369
virtual void io_change()
Definition: triggerbox.h:293
samplepos_t final_processed_sample
Definition: triggerbox.h:449
static void request_trigger_delete(Trigger *t)
static Trigger *const MagicClearPointerValue
Definition: triggerbox.h:423
PBD::ScopedConnection region_connection
Definition: triggerbox.h:497
virtual void set_end(timepos_t const &)=0
PBD::Property< int > _follow_action_probability
Definition: triggerbox.h:154
virtual void jump_stop(BufferSet &bufs, pframes_t dest_offset)
virtual int set_region_in_worker_thread(std::shared_ptr< Region >)=0
virtual void check_edit_swap(timepos_t const &time, bool playing, BufferSet &bufs)=0
virtual void unset_patch_change(uint8_t channel)
Definition: triggerbox.h:408
virtual timepos_t compute_end(Temporal::TempoMap::SharedPtr const &, Temporal::BBT_Time const &, samplepos_t, Temporal::Beats &)=0
virtual void jump_start()
virtual void start_and_roll_to(samplepos_t start, samplepos_t position, uint32_t cnt)=0
void when_stopped_during_run(BufferSet &bufs, pframes_t dest_offset)
virtual void adjust_bounds(Temporal::timepos_t const &start, Temporal::timepos_t const &end, Temporal::timecnt_t const &length, bool from_region)=0
std::atomic< int > _unbang
Definition: triggerbox.h:456
bool will_follow() const
Definition: triggerbox.h:315
virtual timepos_t start_offset() const =0
int set_state(const XMLNode &, int version)
State state() const
Definition: triggerbox.h:329
PBD::Signal< void()> ArmChanged
Definition: triggerbox.h:305
PBD::Property< std::string > _name
Definition: triggerbox.h:169
virtual ~Trigger()
Definition: triggerbox.h:144
PBD::Property< gain_t > _gain
Definition: triggerbox.h:160
std::shared_ptr< TriggerBox > boxptr() const
bool active() const
Definition: triggerbox.h:328
static void make_property_quarks()
void copy_to_ui_state()
uint32_t index() const
Definition: triggerbox.h:338
virtual SegmentDescriptor get_segment_descriptor() const =0
Temporal::BBT_Argument compute_start(Temporal::TempoMap::SharedPtr const &, samplepos_t start, samplepos_t end, Temporal::BBT_Offset const &q, samplepos_t &start_samples, bool &will_start)
virtual void disarm()
samplepos_t expected_end_sample
Definition: triggerbox.h:492
std::shared_ptr< Region > the_region() const
Definition: triggerbox.h:335
PBD::Property< uint32_t > _follow_count
Definition: triggerbox.h:155
virtual void set_used_channels(Evoral::SMF::UsedChannels)
Definition: triggerbox.h:403
virtual int set_region_in_worker_thread_from_capture(std::shared_ptr< Region >)=0
PBD::Property< StretchMode > _stretch_mode
Definition: triggerbox.h:165
void set_ui_state(UIState &state)
virtual void _arm(Temporal::BBT_Offset const &)
Trigger(uint32_t index, TriggerBox &)
virtual void set_legato_offset(timepos_t const &offset)=0
void shutdown_from_fwd()
timepos_t current_pos() const
gain_t _pending_velocity_gain
Definition: triggerbox.h:462
virtual timepos_t natural_length() const =0
virtual void captured(SlotArmInfo &)
Definition: triggerbox.h:299
uint32_t _index
Definition: triggerbox.h:457
virtual void retrigger()
bool cue_launched() const
Definition: triggerbox.h:318
void set_pending(Trigger *)
void arm(Temporal::BBT_Offset duration=Temporal::BBT_Offset())
Definition: triggerbox.h:300
virtual void reload(BufferSet &, void *)=0
virtual void bounds_changed(Temporal::timepos_t const &start, Temporal::timepos_t const &end, Temporal::timecnt_t const &len)
virtual void setup_stretcher()=0
virtual bool probably_oneshot() const =0
void set_velocity_gain(gain_t g)
Definition: triggerbox.h:416
gain_t _velocity_gain
Definition: triggerbox.h:463
void stop_quantized()
virtual void _startup(BufferSet &, pframes_t dest_offset, Temporal::BBT_Offset const &)
UIState ui_state
Definition: triggerbox.h:450
std::shared_ptr< Region > _region
Definition: triggerbox.h:447
void startup_from_ffwd(BufferSet &, uint32_t loop_cnt)
virtual void set_length(timecnt_t const &)=0
std::atomic< PendingSwap * > pending_swap
Definition: triggerbox.h:519
virtual double segment_tempo() const =0
PBD::Property< bool > _legato
Definition: triggerbox.h:159
virtual void unset_all_patch_changes()
Definition: triggerbox.h:409
Trigger * swap_pending(Trigger *)
PBD::Property< color_t > _color
Definition: triggerbox.h:170
void begin_switch(TriggerPtr)
Evoral::SMF::UsedChannels _used_channels
Definition: triggerbox.h:468
bool compute_quantized_transition(samplepos_t start_sample, Temporal::Beats const &start, Temporal::Beats const &end, Temporal::BBT_Argument &t_bbt, Temporal::Beats &t_beats, samplepos_t &t_samples, Temporal::TempoMap::SharedPtr const &tmap, Temporal::BBT_Offset const &q)
XMLNode & get_state() const
PBD::Property< Temporal::BBT_Offset > _follow_length
Definition: triggerbox.h:157
static PBD::Signal< void(PBD::PropertyChange, Trigger *)> TriggerPropertyChange
Definition: triggerbox.h:436
void set_region(std::shared_ptr< Region >, bool use_thread=true)
double estimated_tempo() const
Definition: triggerbox.h:394
void get_ui_state(UIState &state) const
void * ui() const
Definition: triggerbox.h:389
UIRequests _requests
Definition: triggerbox.h:452
std::atomic< Trigger * > _pending
Definition: triggerbox.h:495
Temporal::BBT_Time _transition_bbt
Definition: triggerbox.h:346
void bang(float velocity=1.0f)
Temporal::Beats transition_beats
Definition: triggerbox.h:345
void maybe_compute_next_transition(samplepos_t start_sample, Temporal::Beats const &start, Temporal::Beats const &end, pframes_t &nframes, pframes_t &dest_offset)
void update_properties()
PBD::Property< bool > _use_follow_length
Definition: triggerbox.h:158
Temporal::BBT_Offset _nxt_quantization
Definition: triggerbox.h:494
virtual void set_segment_tempo(double t)=0
virtual bool playable() const =0
void send_property_change(PBD::PropertyChange pc)
virtual pframes_t run(BufferSet &, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const &start, Temporal::Beats const &end, pframes_t nframes, pframes_t offset, double bpm, pframes_t &quantize_offset)=0
virtual void set_start(timepos_t const &)=0
void set_next_trigger(int n)
void start_and_roll_to(samplepos_t start_pos, samplepos_t end_position, TriggerType &trigger, pframes_t(TriggerType::*run_method)(BufferSet &bufs, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const &start_beats, Temporal::Beats const &end_beats, pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t &), uint32_t cnt)
bool explicitly_stopped() const
Definition: triggerbox.h:384
TriggerBox & _box
Definition: triggerbox.h:451
bool _explicitly_stopped
Definition: triggerbox.h:461
PBD::Property< bool > _allow_patch_changes
Definition: triggerbox.h:164
double _segment_tempo
Definition: triggerbox.h:478
std::atomic< unsigned int > last_property_generation
Definition: triggerbox.h:496
virtual void tempo_map_changed()
Definition: triggerbox.h:284
void startup(BufferSet &, pframes_t dest_offset, Temporal::BBT_Offset const &start_quantization=Temporal::BBT_Offset(9, 3, 0))
bool internal_use_follow_length() const
bool is_set() const
Definition: PatchChange.h:110
std::bitset< 16 > UsedChannels
Definition: SMF.h:108
Definition: id.h:34
std::shared_ptr< TempoMap const > SharedPtr
Definition: xml++.h:114
GtkImageIconNameData name
Definition: gtkimage.h:6
#define LIBARDOUR_API
PBD::PropertyDescriptor< uint32_t > queued
PBD::PropertyDescriptor< gain_t > gain
PBD::PropertyDescriptor< bool > legato
PBD::PropertyDescriptor< bool > tempo_meter
PBD::PropertyDescriptor< Temporal::BBT_Offset > follow_length
PBD::PropertyDescriptor< bool > use_follow_length
PBD::PropertyDescriptor< bool > running
PBD::PropertyDescriptor< Trigger::LaunchStyle > launch_style
PBD::PropertyDescriptor< uint32_t > color
PBD::PropertyDescriptor< uint32_t > currently_playing
PBD::PropertyDescriptor< int > follow_action_probability
PBD::PropertyDescriptor< bool > allow_patch_changes
PBD::PropertyDescriptor< timecnt_t > length
PBD::PropertyDescriptor< bool > cue_isolated
PBD::PropertyDescriptor< Temporal::BBT_Offset > quantization
PBD::PropertyDescriptor< bool > region
PBD::PropertyDescriptor< bool > patch_change
PBD::PropertyDescriptor< FollowAction > follow_action1
PBD::PropertyDescriptor< timepos_t > start
PBD::PropertyDescriptor< float > velocity_effect
PBD::PropertyDescriptor< FollowAction > follow_action0
PBD::PropertyDescriptor< uint32_t > follow_count
PBD::PropertyDescriptor< bool > stretchable
PBD::PropertyDescriptor< bool > used_channels
PBD::PropertyDescriptor< Trigger::StretchMode > stretch_mode
PBD::PropertyDescriptor< bool > channel_map
PBD::RingBuffer< CueRecord > CueRecords
Definition: triggerbox.h:820
std::shared_ptr< Trigger > TriggerPtr
Definition: triggerbox.h:83
uint32_t pframes_t
std::vector< CueEvent > CueEvents
Temporal::samplecnt_t samplecnt_t
uint32_t color_t
Definition: triggerbox.h:77
RTMidiBufferBase< Temporal::Beats, Temporal::Beats > RTMidiBufferBeats
Definition: triggerbox.h:86
std::string cue_marker_name(int32_t)
Temporal::samplepos_t samplepos_t
void flush()
DebugBits Properties
Definition: axis_view.h:42
DEFINE_ENUM_CONVERT(ARDOUR::DSP::PerceptualAnalyzer::Speed)
samplecnt_t append(Sample const *src, samplecnt_t cnt, uint32_t chan)
void alloc(samplecnt_t cnt, uint32_t nchans)
int32_t cue_number
Definition: triggerbox.h:811
static const int32_t stop_all
Definition: triggerbox.h:817
CueRecord(int32_t cn, samplepos_t t)
Definition: triggerbox.h:814
samplepos_t when
Definition: triggerbox.h:812
RTMidiBufferBeats * rt_midibuffer
Definition: triggerbox.h:737
Temporal::Beats end_beats
Definition: triggerbox.h:831
AudioTrigger::AudioData audio_buf
Definition: triggerbox.h:835
void reset(Trigger &)
samplepos_t end_samples
Definition: triggerbox.h:832
Temporal::Beats start_beats
Definition: triggerbox.h:829
samplecnt_t captured
Definition: triggerbox.h:833
samplepos_t start_samples
Definition: triggerbox.h:830
RTMidiBufferBeats * midi_buf
Definition: triggerbox.h:834
RubberBand::RubberBandStretcher * stretcher
Definition: triggerbox.h:836
Temporal::timecnt_t duration
Definition: triggerbox.h:789
static PBD::MultiAllocSingleReleasePool * pool
Definition: triggerbox.h:795
std::shared_ptr< Region > region
Definition: triggerbox.h:786
Temporal::timepos_t position
Definition: triggerbox.h:790
static PBD::MultiAllocSingleReleasePool * pool
Definition: triggerbox.h:1067
std::atomic< bool > stop_all
Definition: triggerbox.h:1002
std::atomic< bool > stop
Definition: triggerbox.h:443
Temporal::BBT_Offset quantization
Definition: triggerbox.h:184
Temporal::BBT_Offset follow_length
Definition: triggerbox.h:185
StretchMode stretch_mode
Definition: triggerbox.h:193
LaunchStyle launch_style
Definition: triggerbox.h:179
FollowAction follow_action0
Definition: triggerbox.h:180
std::atomic< unsigned int > generation
Definition: triggerbox.h:177
Evoral::SMF::UsedChannels used_channels
Definition: triggerbox.h:195
Evoral::PatchChange< MidiBuffer::TimeType > patch_change[16]
Definition: triggerbox.h:196
FollowAction follow_action1
Definition: triggerbox.h:181
#define TRIGGERBOX_PROPERTY_DECL_CONST_REF(name, type)
Definition: triggerbox.h:242
#define TRIGGERBOX_PROPERTY_DECL(name, type)
Definition: triggerbox.h:241