Vapor: add option to sync processing to a 512 sample cycle

This commit is contained in:
Robin Gareus 2024-02-27 23:16:54 +01:00
parent 3c61d1150b
commit 8d0704dda2
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
4 changed files with 55 additions and 5 deletions

View File

@ -35,6 +35,7 @@
#endif
#include "ardour/chan_mapping.h"
#include "ardour/fixed_delay.h"
#include "ardour/lufs_meter.h"
#include "ardour/monitor_processor.h"
#include "ardour/processor.h"
@ -109,6 +110,7 @@ public:
/* XXX this is only for testing */
void set_bed_mix (bool on, std::string const& ref, int* cmap = NULL);
void set_sync_and_return (bool on);
int set_state (XMLNode const&, int version);
@ -124,6 +126,7 @@ private:
void evaluate (size_t id, std::shared_ptr<SurroundPannable> const&, timepos_t const& , pframes_t, bool force = false);
void reset_object_map ();
void latency_changed ();
std::shared_ptr<LV2Plugin> _surround_processor;
@ -188,6 +191,8 @@ private:
bool _rolling;
bool _with_bed;
std::string _export_reference;
bool _sync_and_align;
FixedDelay _delaybuffers;
std::atomic<int> _flush;
};

View File

@ -1922,6 +1922,7 @@ LuaBindings::common (lua_State* L)
.deriveWSPtrClass <SurroundReturn, Processor> ("SurroundReturn")
.addFunction ("set_bed_mix", &SurroundReturn::set_bed_mix)
.addFunction ("set_sync_and_return", &SurroundReturn::set_sync_and_return)
.addFunction ("have_au_renderer", &SurroundReturn::have_au_renderer)
.addFunction ("load_au_preset", &SurroundReturn::load_au_preset)
.addFunction ("set_au_param", &SurroundReturn::set_au_param)

View File

@ -299,6 +299,7 @@ Route::init ()
if (is_surround_master ()) {
_meter_point = _pending_meter_point = MeterPreFader;
_surround_return.reset (new SurroundReturn (_session, this));
_surround_return->set_owner (this);
_surround_return->activate ();
panner_shell()->set_bypassed (true);

View File

@ -91,6 +91,7 @@ SurroundReturn::SurroundReturn (Session& s, Route* r)
, _export_end (0)
, _rolling (false)
, _with_bed (false)
, _sync_and_align (false)
{
#if !(defined(LV2_EXTENDED) && defined(HAVE_LV2_1_10_0))
throw failed_constructor ();
@ -115,6 +116,9 @@ SurroundReturn::SurroundReturn (Session& s, Route* r)
_trim->configure_io (cca128, cca128);
_trim->activate ();
ChanCount cca20 (ChanCount (DataType::AUDIO, 20)); // 7.1.4 + binaural + 5.1
_delaybuffers.configure (cca20, 512);
for (size_t i = 0; i < max_object_id; ++i) {
_current_render_mode[i] = -1;
_channel_id_map[i] = i;
@ -324,7 +328,7 @@ SurroundReturn::set_block_size (pframes_t nframes)
samplecnt_t
SurroundReturn::signal_latency () const
{
return _surround_processor->signal_latency ();
return _surround_processor->signal_latency () + _delaybuffers.delay ();
}
void
@ -333,6 +337,14 @@ SurroundReturn::flush ()
_flush.store (1);
}
void
SurroundReturn::latency_changed ()
{
LatencyChanged ();
assert (owner());
static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
}
void
SurroundReturn::reset_object_map ()
{
@ -364,6 +376,15 @@ SurroundReturn::set_bed_mix (bool on, std::string const& ref, int* cmap)
}
}
void
SurroundReturn::set_sync_and_return (bool on)
{
if (_sync_and_align == on) {
return;
}
_sync_and_align = on;
}
void
SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
{
@ -376,6 +397,27 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
_surround_processor->flush ();
}
if (_sync_and_align) {
if (!_rolling && start_sample != end_sample) {
_delaybuffers.flush ();
_surround_processor->deactivate();
_surround_processor->activate();
}
if (0 != (playback_offset() % 512)) {
ChanCount cca20 (ChanCount (DataType::AUDIO, 20)); // 7.1.4 + binaural + 5.1
if (_delaybuffers.delay () == 0) {
_delaybuffers.set (cca20, 512 - playback_offset() % 512);
} else {
_delaybuffers.set (cca20, 0);
}
latency_changed ();
}
} else if (_delaybuffers.delay () != 0) {
ChanCount cca20 (ChanCount (DataType::AUDIO, 20)); // 7.1.4 + binaural + 5.1
_delaybuffers.set (cca20, 0);
latency_changed ();
}
bool with_bed = _with_bed;
bufs.set_count (_configured_output);
@ -438,7 +480,7 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
* IOW: end_sample == next cycle's start_sample;
*/
if (nframes < 2) {
evaluate (id, p, timepos_t (start_sample), 0);
evaluate (id, p, timepos_t (start_sample + latency), 0);
} else {
bool found_event = false;
timepos_t start (start_sample + latency);
@ -456,7 +498,7 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
}
/* inform live renderer */
if (!found_event && !_exporting) {
evaluate (id, p, end, nframes - 1);
evaluate (id, p, start, 0);
}
}
}
@ -583,8 +625,9 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
_surround_processor->connect_and_run (_surround_bufs, start_sample, end_sample, speed, _in_map, _out_map, nframes, 0);
BufferSet::iterator i = _surround_bufs.begin (DataType::AUDIO);
for (BufferSet::iterator o = bufs.begin (DataType::AUDIO); o != bufs.end (DataType::AUDIO); ++i, ++o) {
o->read_from (*i, nframes);
uint32_t idx = 0;
for (BufferSet::iterator o = bufs.begin (DataType::AUDIO); o != bufs.end (DataType::AUDIO); ++i, ++o, ++idx) {
_delaybuffers.delay (DataType::AUDIO, idx, *o, *i, nframes);
}
if (_exporting) {