summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2018-12-24 02:29:24 +0100
committerRobin Gareus <robin@gareus.org>2018-12-24 02:29:24 +0100
commita0994b16dd9ef2d7d78938541278580b598f5f25 (patch)
tree0c97f2e43d8ce87a83708cc9997db41f4269a7cc /libs
parent517b5f091f51d8687e98fc439e2023791741d48f (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.h35
-rw-r--r--libs/ardour/convolver.cc38
-rw-r--r--libs/ardour/luabindings.cc12
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)