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.
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#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<GainControl> gc);
|
||||
|
||||
using RTARingBuffer = PBD::RingBuffer<ARDOUR::Sample>;
|
||||
using RTARingBufferPtr = std::shared_ptr<RTARingBuffer>;
|
||||
using RTABufferList = std::vector<RTARingBufferPtr>;
|
||||
using RTABufferListPtr = std::shared_ptr<RTABufferList>;
|
||||
|
||||
void set_analysis_buffers (RTABufferListPtr rb) {
|
||||
_rtabuffers = rb;
|
||||
}
|
||||
bool analysis_active () const;
|
||||
void set_analysis_active (bool);
|
||||
|
||||
void set_polarity_control (std::shared_ptr<AutomationControl> ac) {
|
||||
_polarity_control = ac;
|
||||
}
|
||||
@@ -152,6 +165,9 @@ private:
|
||||
std::shared_ptr<GainControl> _gain_control;
|
||||
std::shared_ptr<AutomationControl> _polarity_control;
|
||||
|
||||
RTABufferListPtr _rtabuffers;
|
||||
std::atomic<bool> _rta_active;
|
||||
|
||||
static bool panners_legal;
|
||||
static PBD::Signal<void()> PannersLegal;
|
||||
|
||||
@@ -164,5 +180,3 @@ private:
|
||||
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ Delivery::Delivery (Session& s, std::shared_ptr<IO> io, std::shared_ptr<Pannable
|
||||
, _current_gain (GAIN_COEFF_ZERO)
|
||||
, _no_outs_cuz_we_no_monitor (false)
|
||||
, _mute_master (mm)
|
||||
, _rta_active (false)
|
||||
, _no_panner_reset (false)
|
||||
{
|
||||
if (pannable) {
|
||||
@@ -87,6 +88,7 @@ Delivery::Delivery (Session& s, std::shared_ptr<Pannable> 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<GainControl> 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()) {
|
||||
|
||||
Reference in New Issue
Block a user