diff options
author | Robin Gareus <robin@gareus.org> | 2018-12-24 02:29:24 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2018-12-24 02:29:24 +0100 |
commit | a0994b16dd9ef2d7d78938541278580b598f5f25 (patch) | |
tree | 0c97f2e43d8ce87a83708cc9997db41f4269a7cc /libs | |
parent | 517b5f091f51d8687e98fc439e2023791741d48f (diff) |
Update Convolver/LuaConvolver
* Add API to allow per-channnel gain and delay
* Fix channel-mapping for stereo IRs w/o true-stereo
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/convolver.h | 35 | ||||
-rw-r--r-- | libs/ardour/convolver.cc | 38 | ||||
-rw-r--r-- | libs/ardour/luabindings.cc | 12 |
3 files changed, 73 insertions, 12 deletions
diff --git a/libs/ardour/ardour/convolver.h b/libs/ardour/ardour/convolver.h index 9d858a1e63..a5b52cd32d 100644 --- a/libs/ardour/ardour/convolver.h +++ b/libs/ardour/ardour/convolver.h @@ -37,7 +37,38 @@ public: Stereo, ///< 2 in, 2 out, stereo IR L -> L, R -> R || 4 chan IR L -> L, L -> R, R -> R, R -> L }; - Convolver (Session&, std::string const&, IRChannelConfig irc = Mono, uint32_t pre_delay = 0); + struct IRSettings { + IRSettings () { + gain = 1.0; + pre_delay = 0.0; + channel_gain[0] = channel_gain[1] = channel_gain[2] = channel_gain[3] = 1.0; + channel_delay[0] = channel_delay[1] = channel_delay[2] = channel_delay[3] = 0; + }; + + float gain; + uint32_t pre_delay; + float channel_gain[4]; + uint32_t channel_delay[4]; + + /* convenient array accessors for Lua bindings */ + float get_channel_gain (unsigned i) const { + if (i < 4) { return channel_gain[i]; } + return 0; + } + void set_channel_gain (unsigned i, float g) { + if (i < 4) { channel_gain[i] = g; } + } + uint32_t get_channel_delay (unsigned i) const { + if (i < 4) { return channel_delay[i]; } + return 0; + } + void set_channel_delay (unsigned i, uint32_t d) { + if (i < 4) { channel_delay[i] = d; } + } + }; + + + Convolver (Session&, std::string const&, IRChannelConfig irc = Mono, IRSettings irs = IRSettings ()); void run (float*, uint32_t); void run_stereo (float* L, float* R, uint32_t); @@ -55,7 +86,7 @@ private: ArdourZita::Convproc _convproc; IRChannelConfig _irc; - uint32_t _initial_delay; + IRSettings _ir_settings; uint32_t _n_samples; uint32_t _max_size; diff --git a/libs/ardour/convolver.cc b/libs/ardour/convolver.cc index d0caa8e669..4cd14672de 100644 --- a/libs/ardour/convolver.cc +++ b/libs/ardour/convolver.cc @@ -36,10 +36,14 @@ using namespace ArdourZita; using ARDOUR::Session; -Convolver::Convolver (Session& session, std::string const& path, IRChannelConfig irc, uint32_t pre_delay) +Convolver::Convolver ( + Session& session, + std::string const& path, + IRChannelConfig irc, + IRSettings irs) : SessionHandleRef (session) , _irc (irc) - , _initial_delay (pre_delay) + , _ir_settings (irs) , _n_samples (0) , _max_size (0) , _offset (0) @@ -131,6 +135,10 @@ Convolver::reconfigure () uint32_t n_imp = n_inputs() * n_outputs (); uint32_t n_chn = _readables.size(); +#ifndef NDEBUG + printf ("Convolver::reconfigure Nin %d Nout %d Nimp %d Nchn %d\n", n_inputs (), n_outputs (), n_imp, n_chn); +#endif + if (_irc == Stereo && n_chn == 3) { /* ignore 3rd channel */ n_chn = 2; @@ -140,12 +148,14 @@ Convolver::reconfigure () n_imp = 2; } + assert (n_imp <= 4); + for (uint32_t c = 0; c < n_imp && rv == 0; ++c) { int ir_c = c % n_chn; int io_o = c % n_outputs(); int io_i; - if (n_imp > n_chn && _irc == Stereo) { + if (n_imp == 2 && _irc == Stereo) { /* (imp, in, out) * Stereo (2, 2, 2) 1: L -> L, 2: R -> R */ @@ -159,14 +169,18 @@ Convolver::reconfigure () io_i = (c / n_outputs()) % n_inputs(); } -#ifndef NDEBUG - printf ("Convolver map: IR-chn %d: in %d -> out %d\n", ir_c + 1, io_i + 1, io_o + 1); -#endif - boost::shared_ptr<Readable> r = _readables[ir_c % n_chn]; + boost::shared_ptr<Readable> r = _readables[ir_c]; assert (r->readable_length () == _max_size); assert (r->n_channels () == 1); + const float chan_gain = _ir_settings.gain * _ir_settings.channel_gain[c]; + const uint32_t chan_delay = _ir_settings.pre_delay + _ir_settings.channel_delay[c]; + +#ifndef NDEBUG + printf ("Convolver map: IR-chn %d: in %d -> out %d (gain: %.1fdB delay; %d)\n", ir_c + 1, io_i + 1, io_o + 1, 20.f * log10f(chan_gain), chan_delay); +#endif + uint32_t pos = 0; while (true) { float ir[8192]; @@ -178,11 +192,17 @@ Convolver::reconfigure () break; } + if (chan_gain != 1.f) { + for (samplecnt_t i = 0; i < ns; ++i) { + ir[i] *= chan_gain; + } + } + rv = _convproc.impdata_create ( /*i/o map */ io_i, io_o, /*stride, de-interleave */1, ir, - _initial_delay + pos, _initial_delay + pos + ns); + chan_delay + pos, chan_delay + pos + ns); if (rv != 0) { break; @@ -193,7 +213,7 @@ Convolver::reconfigure () if (pos == _max_size) { break; } - }; + } } if (rv == 0) { diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 9fb807e5de..f3eac8529f 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -2412,8 +2412,18 @@ LuaBindings::common (lua_State* L) .addRefFunction ("read", &ARDOUR::LTCReader::read) .endClass () + .beginClass <DSP::Convolver::IRSettings> ("IRSettings") + .addVoidConstructor () + .addData ("gain", &DSP::Convolver::IRSettings::gain) + .addData ("pre_delay", &DSP::Convolver::IRSettings::pre_delay) + .addFunction ("get_channel_gain", &ARDOUR::DSP::Convolver::IRSettings::get_channel_gain) + .addFunction ("set_channel_gain", &ARDOUR::DSP::Convolver::IRSettings::set_channel_gain) + .addFunction ("get_channel_delay", &ARDOUR::DSP::Convolver::IRSettings::get_channel_delay) + .addFunction ("set_channel_delay", &ARDOUR::DSP::Convolver::IRSettings::set_channel_delay) + .endClass () + .beginClass <DSP::Convolver> ("Convolver") - .addConstructor <void (*) (Session&, std::string const&, DSP::Convolver::IRChannelConfig, uint32_t)> () + .addConstructor <void (*) (Session&, std::string const&, DSP::Convolver::IRChannelConfig, DSP::Convolver::IRSettings)> () .addFunction ("run", &ARDOUR::DSP::Convolver::run) .addFunction ("run_stereo", &ARDOUR::DSP::Convolver::run_stereo) .addFunction ("latency", &ARDOUR::DSP::Convolver::latency) |