diff options
-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 | ||||
-rw-r--r-- | scripts/_convolv.lua | 4 |
4 files changed, 76 insertions, 13 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) diff --git a/scripts/_convolv.lua b/scripts/_convolv.lua index b2f6b477ab..b8d82627fb 100644 --- a/scripts/_convolv.lua +++ b/scripts/_convolv.lua @@ -26,7 +26,9 @@ function dsp_configure (ins, outs) mode = ARDOUR.DSP.IRChannelConfig.Stereo end - conv = ARDOUR.DSP.Convolver (Session, ir_file, mode, 0) + local irs = ARDOUR.DSP.IRSettings() + irs.gain = 0.5 + conv = ARDOUR.DSP.Convolver (Session, ir_file, mode, irs) collectgarbage () end |