13
0

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

View File

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

View File

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

View File

@ -91,6 +91,7 @@ SurroundReturn::SurroundReturn (Session& s, Route* r)
, _export_end (0) , _export_end (0)
, _rolling (false) , _rolling (false)
, _with_bed (false) , _with_bed (false)
, _sync_and_align (false)
{ {
#if !(defined(LV2_EXTENDED) && defined(HAVE_LV2_1_10_0)) #if !(defined(LV2_EXTENDED) && defined(HAVE_LV2_1_10_0))
throw failed_constructor (); throw failed_constructor ();
@ -115,6 +116,9 @@ SurroundReturn::SurroundReturn (Session& s, Route* r)
_trim->configure_io (cca128, cca128); _trim->configure_io (cca128, cca128);
_trim->activate (); _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) { for (size_t i = 0; i < max_object_id; ++i) {
_current_render_mode[i] = -1; _current_render_mode[i] = -1;
_channel_id_map[i] = i; _channel_id_map[i] = i;
@ -324,7 +328,7 @@ SurroundReturn::set_block_size (pframes_t nframes)
samplecnt_t samplecnt_t
SurroundReturn::signal_latency () const SurroundReturn::signal_latency () const
{ {
return _surround_processor->signal_latency (); return _surround_processor->signal_latency () + _delaybuffers.delay ();
} }
void void
@ -333,6 +337,14 @@ SurroundReturn::flush ()
_flush.store (1); _flush.store (1);
} }
void
SurroundReturn::latency_changed ()
{
LatencyChanged ();
assert (owner());
static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
}
void void
SurroundReturn::reset_object_map () 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 void
SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool) 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 (); _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; bool with_bed = _with_bed;
bufs.set_count (_configured_output); 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; * IOW: end_sample == next cycle's start_sample;
*/ */
if (nframes < 2) { if (nframes < 2) {
evaluate (id, p, timepos_t (start_sample), 0); evaluate (id, p, timepos_t (start_sample + latency), 0);
} else { } else {
bool found_event = false; bool found_event = false;
timepos_t start (start_sample + latency); timepos_t start (start_sample + latency);
@ -456,7 +498,7 @@ SurroundReturn::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_
} }
/* inform live renderer */ /* inform live renderer */
if (!found_event && !_exporting) { 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); _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); BufferSet::iterator i = _surround_bufs.begin (DataType::AUDIO);
for (BufferSet::iterator o = bufs.begin (DataType::AUDIO); o != bufs.end (DataType::AUDIO); ++i, ++o) { uint32_t idx = 0;
o->read_from (*i, nframes); 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) { if (_exporting) {