2 Copyright (C) 2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <ardour/amp.h>
23 #include <ardour/buffer_set.h>
24 #include <ardour/buffer.h>
29 /** Apply a declicked gain to the audio buffers of @a bufs */
31 Amp::run (BufferSet& bufs, jack_nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity)
33 if (bufs.count().get(DataType::AUDIO) == 0)
36 assert(bufs.buffer_capacity(DataType::AUDIO) >= nframes);
38 // if we don't need to declick, defer to apply_simple_gain
39 if (initial == target) {
40 apply_simple_gain(bufs, nframes, invert_polarity ? target : -target);
43 const jack_nframes_t declick = std::min ((jack_nframes_t)128, nframes);
45 double fractional_shift = -1.0/declick;
46 double fractional_pos;
47 gain_t polscale = invert_polarity ? -1.0f : 1.0f;
52 if (target < initial) {
53 /* fade out: remove more and more of delta from initial */
54 delta = -(initial - target);
56 /* fade in: add more and more of delta from initial */
57 delta = target - initial;
60 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
61 Sample* const buffer = i->data(nframes);
65 for (jack_nframes_t nx = 0; nx < declick; ++nx) {
66 buffer[nx] *= polscale * (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos))));
67 fractional_pos += fractional_shift;
70 /* now ensure the rest of the buffer has the target value applied, if necessary. */
72 if (declick != nframes) {
74 if (invert_polarity) {
79 memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
80 } else if (target != 1.0) {
81 for (jack_nframes_t nx = declick; nx < nframes; ++nx) {
90 Amp::apply_simple_gain (BufferSet& bufs, jack_nframes_t nframes, gain_t target)
92 for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
93 i->apply_gain(target, nframes);