From e12d8b3769ab688f10d5a34b86a6bfa4102faaf6 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 25 Mar 2025 03:02:06 +0100 Subject: [PATCH] Add API to tap signal from a Delivery to RTA Rater than having each Delivery Object provide a Ringbuffer, which is unused most of the time, the GUI will provide them on demand. We need to be careful of lifetime, and use `rt_safe_delete` in case the Delivery holds the last instance. --- libs/ardour/ardour/delivery.h | 18 +++++++++++++++-- libs/ardour/delivery.cc | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index 4cba84788a..1b6314fa6f 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -24,6 +24,8 @@ #include +#include "pbd/ringbuffer.h" + #include "ardour/libardour_visibility.h" #include "ardour/types.h" #include "ardour/chan_count.h" @@ -110,6 +112,17 @@ public: void set_gain_control (std::shared_ptr gc); + using RTARingBuffer = PBD::RingBuffer; + using RTARingBufferPtr = std::shared_ptr; + using RTABufferList = std::vector; + using RTABufferListPtr = std::shared_ptr; + + void set_analysis_buffers (RTABufferListPtr rb) { + _rtabuffers = rb; + } + bool analysis_active () const; + void set_analysis_active (bool); + void set_polarity_control (std::shared_ptr ac) { _polarity_control = ac; } @@ -152,6 +165,9 @@ private: std::shared_ptr _gain_control; std::shared_ptr _polarity_control; + RTABufferListPtr _rtabuffers; + std::atomic _rta_active; + static bool panners_legal; static PBD::Signal PannersLegal; @@ -164,5 +180,3 @@ private: } // namespace ARDOUR - - diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 4433d18efc..4c84e960c8 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -63,6 +63,7 @@ Delivery::Delivery (Session& s, std::shared_ptr io, std::shared_ptr pannable, std::shared_ , _current_gain (GAIN_COEFF_ZERO) , _no_outs_cuz_we_no_monitor (false) , _mute_master (mm) + , _rta_active (false) , _no_panner_reset (false) { if (pannable) { @@ -199,6 +201,19 @@ Delivery::set_gain_control (std::shared_ptr gc) { } } +bool +Delivery::analysis_active () const +{ + return _rta_active.load (); +} + +void +Delivery::set_analysis_active (bool en) +{ + // TODO latch with session wide enable, sync'ed at process start + _rta_active.store (en); +} + /** Caller must hold process lock */ bool Delivery::configure_io (ChanCount in, ChanCount out) @@ -299,6 +314,14 @@ Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample bufs.set_count (output_buffers().count ()); Amp::apply_simple_gain (bufs, nframes, GAIN_COEFF_ZERO); } + + RTABufferListPtr rtabuffers = _rtabuffers; + if (_rta_active.load () && rtabuffers && !rtabuffers->empty ()) { + BufferSet& silent_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1)); + for (auto const& rb : *rtabuffers) { + rb->write (silent_bufs.get_audio(0).data(), nframes); + } + } return; } else if (tgain != GAIN_COEFF_UNITY) { @@ -320,6 +343,20 @@ Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample _amp->run (bufs, start_sample, end_sample, speed, nframes, true); } + RTABufferListPtr rtabuffers = _rtabuffers; + if (_rta_active.load () && rtabuffers && !rtabuffers->empty ()) { + uint32_t n_audio = bufs.count().n_audio(); + uint32_t n = 0; + for (auto const& rb: *rtabuffers) { + if (n < n_audio) { + rb->write (bufs.get_audio (n++).data(), nframes); + } else { + BufferSet& silent_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1)); + rb->write (silent_bufs.get_audio(0).data(), nframes); + } + } + } + // Panning if (_panshell && !_panshell->bypassed() && _panshell->panner()) {