Remove unused fluidsynth setting (since fluidsynth 2.0)
[ardour.git] / libs / ardour / convolver.cc
index d0caa8e669ab16983802aacf248d7dff3b854ada..19bdf64b5b0e3d07b36d763af81def7f899278ac 100644 (file)
@@ -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)
@@ -78,7 +82,7 @@ Convolver::Convolver (Session& session, std::string const& path, IRChannelConfig
                }
        }
 
-       if (_readables.empty()) {
+       if (_readables.empty ()) {
                PBD::error << string_compose (_("Convolver: IR \"%1\" no usable audio-channels sound."), path) << endmsg;
                throw failed_constructor ();
        }
@@ -95,11 +99,11 @@ Convolver::reconfigure ()
        _convproc.cleanup ();
        _convproc.set_options (0);
 
-       assert (!_readables.empty());
+       assert (!_readables.empty ());
 
-       _offset = 0;
-       _n_samples = _session.get_block_size();
-       _max_size = _readables[0]->readable_length();
+       _offset    = 0;
+       _n_samples = _session.get_block_size ();
+       _max_size  = _readables[0]->readable_length ();
 
        uint32_t power_of_two;
        for (power_of_two = 1; 1U << power_of_two < _n_samples; ++power_of_two);
@@ -128,8 +132,12 @@ Convolver::reconfigure ()
         *    4chan file:  L -> L, L -> R, R -> R, R -> L
         */
 
-       uint32_t n_imp = n_inputs() * n_outputs ();
-       uint32_t n_chn = _readables.size();
+       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 */
@@ -140,33 +148,39 @@ 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_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
                         */
-                       io_i = c % n_inputs();
+                       io_i = c % n_inputs ();
                } else {
                        /*           (imp, in, out)
                         * Mono         (1, 1, 1)   1: M -> M
                         * MonoToStereo (2, 1, 2)   1: M -> L, 2: M -> R
                         * Stereo       (4, 2, 2)   1: L -> L, 2: L -> R, 3: R -> L, 4: R -> R
                         */
-                       io_i = (c / n_outputs()) % n_inputs();
+                       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,
+                                       /*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) {
@@ -217,7 +237,8 @@ Convolver::reconfigure ()
 }
 
 bool
-Convolver::ready () const {
+Convolver::ready () const
+{
        return _configured && _convproc.state () == Convproc::ST_PROC;
 }
 
@@ -227,14 +248,14 @@ Convolver::run (float* buf, uint32_t n_samples)
        assert (_convproc.state () == Convproc::ST_PROC);
        assert (_irc == Mono);
 
-       uint32_t done = 0;
+       uint32_t done   = 0;
        uint32_t remain = n_samples;
 
        while (remain > 0) {
                uint32_t ns = std::min (remain, _n_samples - _offset);
 
-               float* const       in  = _convproc.inpdata (/*channel*/0);
-               float const* const out = _convproc.outdata (/*channel*/0);
+               float* const       in  = _convproc.inpdata (/*channel*/ 0);
+               float const* const out = _convproc.outdata (/*channel*/ 0);
 
                memcpy (&in[_offset], &buf[done], sizeof (float) * ns);
                memcpy (&buf[done], &out[_offset], sizeof (float) * ns);
@@ -256,18 +277,18 @@ Convolver::run_stereo (float* left, float* right, uint32_t n_samples)
        assert (_convproc.state () == Convproc::ST_PROC);
        assert (_irc != Mono);
 
-       uint32_t done = 0;
+       uint32_t done   = 0;
        uint32_t remain = n_samples;
 
        while (remain > 0) {
                uint32_t ns = std::min (remain, _n_samples - _offset);
 
-               memcpy (&_convproc.inpdata(0)[_offset], &left[done], sizeof (float) * ns);
+               memcpy (&_convproc.inpdata (0)[_offset], &left[done], sizeof (float) * ns);
                if (_irc >= Stereo) {
-                       memcpy (&_convproc.inpdata(1)[_offset], &right[done], sizeof (float) * ns);
+                       memcpy (&_convproc.inpdata (1)[_offset], &right[done], sizeof (float) * ns);
                }
-               memcpy (&left[done],  &_convproc.outdata(0)[_offset], sizeof (float) * ns);
-               memcpy (&right[done], &_convproc.outdata(1)[_offset], sizeof (float) * ns);
+               memcpy (&left[done],  &_convproc.outdata (0)[_offset], sizeof (float) * ns);
+               memcpy (&right[done], &_convproc.outdata (1)[_offset], sizeof (float) * ns);
 
                _offset += ns;
                done    += ns;