From 02eb39325ffd6d160e34c25a3963f8ec2d89543d Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 15 Dec 2021 18:15:58 -0700 Subject: [PATCH] triggerbox: fix channel handling for audio We do not modify the audio I/O of the parent route, and process at most std::min (route_inputs,region_channels). --- libs/ardour/ardour/triggerbox.h | 2 ++ libs/ardour/triggerbox.cc | 41 +++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h index 2c2940bc15..02b1631f7f 100644 --- a/libs/ardour/ardour/triggerbox.h +++ b/libs/ardour/ardour/triggerbox.h @@ -127,6 +127,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { virtual void set_end (timepos_t const &) = 0; virtual void set_length (timecnt_t const &) = 0; virtual void reload (BufferSet&, void*) = 0; + virtual void io_change () {} virtual double position_as_fraction() const = 0; virtual void set_expected_end_sample (Temporal::TempoMap::SharedPtr const &, Temporal::BBT_Time const &) = 0; @@ -284,6 +285,7 @@ class LIBARDOUR_API AudioTrigger : public Trigger { timepos_t current_length() const; /* offset from start of data */ timepos_t natural_length() const; /* offset from start of data */ void reload (BufferSet&, void*); + void io_change (); double position_as_fraction() const; diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index 6b99874784..1ea09f815c 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -858,6 +858,15 @@ AudioTrigger::determine_tempo () cerr << "barcnt = " << round (_barcnt) << endl; } +void +AudioTrigger::io_change () +{ + if (_stretcher) { + setup_stretcher (); + } +} + +/* This exists so that we can play with the value easily. Currently, 1024 seems as good as any */ static const samplecnt_t rb_blocksize = 1024; void @@ -871,18 +880,15 @@ AudioTrigger::setup_stretcher () } boost::shared_ptr ar (boost::dynamic_pointer_cast (_region)); - const uint32_t nchans = ar->n_channels(); + const uint32_t nchans = std::min (_box.input_streams().n_audio(), ar->n_channels()); /* XXX maybe get some of these options from region properties (when/if we have them) ? */ RubberBandStretcher::Options options = RubberBandStretcher::Option (RubberBandStretcher::OptionProcessRealTime | RubberBandStretcher::OptionTransientsCrisp); - if (!_stretcher) { - _stretcher = new RubberBandStretcher (_box.session().sample_rate(), nchans, options, 1.0, 1.0); - } else { - _stretcher->reset (); - } + delete _stretcher; + _stretcher = new RubberBandStretcher (_box.session().sample_rate(), nchans, options, 1.0, 1.0); _stretcher->setMaxProcessSize (rb_blocksize); } @@ -946,7 +952,8 @@ pframes_t AudioTrigger::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, bool passthru, double bpm) { boost::shared_ptr ar = boost::dynamic_pointer_cast(_region); - const uint32_t nchans = ar->n_channels(); + /* We do not modify the I/O of our parent route, so we process only min (bufs.n_audio(),region.channels()) */ + const uint32_t nchans = std::min (bufs.count().n_audio(), ar->n_channels()); const pframes_t orig_nframes = nframes; int avail = 0; BufferSet& scratch (_box.session().get_scratch_buffers (ChanCount (DataType::AUDIO, nchans))); @@ -1843,9 +1850,15 @@ TriggerBox::add_midi_sidechain (std::string const & name) bool TriggerBox::can_support_io_configuration (const ChanCount& in, ChanCount& out) { - out.set_audio (std::max (out.n_audio(), 2U)); /* for now, enforce stereo output */ + /* if this is an audio trigger, let it be known that we have at least 1 audio output. + */ + if (_data_type == DataType::AUDIO) { + out.set_audio (std::max (in.n_audio(), 1U)); + } + /* if this is a MIDI trigger, let it be known that we have at least 1 MIDI output. + */ if (_data_type == DataType::MIDI) { - out.set_midi (std::max (out.n_midi(), 1U)); + out.set_midi (std::max (in.n_midi(), 1U)); } return true; } @@ -1856,7 +1869,15 @@ TriggerBox::configure_io (ChanCount in, ChanCount out) if (_sidechain) { _sidechain->configure_io (in, out); } - return Processor::configure_io (in, out); + + bool ret = Processor::configure_io (in, out); + + if (ret) { + for (uint64_t n = 0; n < all_triggers.size(); ++n) { + all_triggers[n]->io_change (); + } + } + } void