do not apply global transport declick to MIDI
authorPaul Davis <paul@linuxaudiosystems.com>
Sun, 25 Jul 2010 19:26:14 +0000 (19:26 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sun, 25 Jul 2010 19:26:14 +0000 (19:26 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7491 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/amp.cc
libs/ardour/ardour/amp.h
libs/ardour/route.cc

index a739b59088c160c74ce320640f265cb04dd7cdbd..36d0c6bf331c08ea68ccb9ede9a8a8bfb8fd7743 100644 (file)
@@ -160,7 +160,6 @@ Amp::apply_gain (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t targ
 
        for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) {
 
-
                MidiBuffer& mb (*i);
 
                for (MidiBuffer::iterator m = mb.begin(); m != mb.end(); ++m) {
@@ -198,6 +197,59 @@ Amp::apply_gain (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t targ
        }
 }
 
+void
+Amp::declick (BufferSet& bufs, nframes_t nframes, int dir)
+{
+        /* Almost exactly like ::apply_gain() but skips MIDI buffers and has fixed initial+target
+           values.
+         */
+
+       if (nframes == 0 || bufs.count().n_total() == 0) {
+               return;
+       }
+
+       const nframes_t declick = std::min ((nframes_t)128, nframes);
+       gain_t         delta, initial, target;
+       double         fractional_shift = -1.0/declick;
+       double         fractional_pos;
+
+       if (dir < 0) {
+               /* fade out: remove more and more of delta from initial */
+               delta = -1.0;
+                initial = 1.0;
+                target = 0.0;
+       } else {
+               /* fade in: add more and more of delta from initial */
+               delta = 1.0;
+                initial = 0.0;
+                target = 1.0;
+       }
+
+       /* Audio Gain */
+
+       for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
+               Sample* const buffer = i->data();
+
+               fractional_pos = 1.0;
+
+               for (nframes_t nx = 0; nx < declick; ++nx) {
+                       buffer[nx] *= (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos))));
+                       fractional_pos += fractional_shift;
+               }
+
+               /* now ensure the rest of the buffer has the target value applied, if necessary. */
+
+               if (declick != nframes) {
+
+                       if (target == 0.0) {
+                               memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
+                       } else if (target != 1.0) {
+                               apply_gain_to_buffer (&buffer[declick], nframes - declick, target);
+                       }
+               }
+       }
+}
+
 void
 Amp::apply_gain (AudioBuffer& buf, nframes_t nframes, gain_t initial, gain_t target)
 {
index c1f6172de1ff9d0caad6d42dfaf60068c06ba18f..1b6baaebd107e636291748430f791054e86feef0 100644 (file)
@@ -62,6 +62,8 @@ public:
         static void apply_gain (AudioBuffer& buf, nframes_t nframes, gain_t initial, gain_t target);
        static void apply_simple_gain(AudioBuffer& buf, nframes_t nframes, gain_t target);
 
+       static void declick (BufferSet& bufs, nframes_t nframes, int dir);
+
        gain_t         gain () const { return _gain_control->user_float(); }
 
        virtual void   set_gain (gain_t g, void *src);
index bd8abae88ba638323601e387ca85614bdbb7b9d5..1d8f3ca18e671611d9cfa33cccd2c067c8c95372 100644 (file)
@@ -413,9 +413,9 @@ Route::process_output_buffers (BufferSet& bufs,
           ----------------------------------------------------------------------------------------- */
 
        if (declick > 0) {
-               Amp::apply_gain (bufs, nframes, 0.0, 1.0);
+               Amp::declick (bufs, nframes, 1);
        } else if (declick < 0) {
-               Amp::apply_gain (bufs, nframes, 1.0, 0.0);
+               Amp::declick (bufs, nframes, -1);
        }
 
        _pending_declick = 0;