X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Faudio_buffers.cc;h=e80142b8e518ad2efe66f5f1c1ee4b90f6dcafa6;hb=f98c4cdec82fc2fbdcc4ca19748d09b0ea0556b4;hp=403babaf7f84bd4b0ff0974d67a4fb5471b93234;hpb=50cb31af16240b248700dab1484d7f07656c66df;p=dcpomatic.git diff --git a/src/lib/audio_buffers.cc b/src/lib/audio_buffers.cc index 403babaf7..e80142b8e 100644 --- a/src/lib/audio_buffers.cc +++ b/src/lib/audio_buffers.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include "audio_buffers.h" @@ -30,69 +31,67 @@ using boost::shared_ptr; * @param frames Number of frames to reserve space for. */ AudioBuffers::AudioBuffers (int channels, int frames) - : _channels (channels) - , _frames (frames) - , _allocated_frames (frames) { - _data = static_cast (malloc (_channels * sizeof (float *))); - if (!_data) { - throw bad_alloc (); - } - - for (int i = 0; i < _channels; ++i) { - _data[i] = static_cast (malloc (frames * sizeof (float))); - if (!_data[i]) { - throw bad_alloc (); - } - } + allocate (channels, frames); } /** Copy constructor. * @param other Other AudioBuffers; data is copied. */ AudioBuffers::AudioBuffers (AudioBuffers const & other) - : _channels (other._channels) - , _frames (other._frames) - , _allocated_frames (other._frames) { - _data = static_cast (malloc (_channels * sizeof (float *))); - if (!_data) { - throw bad_alloc (); - } - - for (int i = 0; i < _channels; ++i) { - _data[i] = static_cast (malloc (_frames * sizeof (float))); - if (!_data[i]) { - throw bad_alloc (); - } - memcpy (_data[i], other._data[i], _frames * sizeof (float)); - } + allocate (other._channels, other._frames); + copy_from (&other, other._frames, 0, 0); } -/* XXX: it's a shame that this is a copy-and-paste of the above; - probably fixable with c++0x. -*/ AudioBuffers::AudioBuffers (boost::shared_ptr other) - : _channels (other->_channels) - , _frames (other->_frames) - , _allocated_frames (other->_frames) { + allocate (other->_channels, other->_frames); + copy_from (other.get(), other->_frames, 0, 0); +} + +AudioBuffers & +AudioBuffers::operator= (AudioBuffers const & other) +{ + if (this == &other) { + return *this; + } + + deallocate (); + allocate (other._channels, other._frames); + copy_from (&other, other._frames, 0, 0); + + return *this; +} + +/** AudioBuffers destructor */ +AudioBuffers::~AudioBuffers () +{ + deallocate (); +} + +void +AudioBuffers::allocate (int channels, int frames) +{ + _channels = channels; + _frames = frames; + _allocated_frames = frames; + _data = static_cast (malloc (_channels * sizeof (float *))); if (!_data) { throw bad_alloc (); } for (int i = 0; i < _channels; ++i) { - _data[i] = static_cast (malloc (_frames * sizeof (float))); + _data[i] = static_cast (malloc (frames * sizeof (float))); if (!_data[i]) { throw bad_alloc (); } - memcpy (_data[i], other->_data[i], _frames * sizeof (float)); } } -/** AudioBuffers destructor */ -AudioBuffers::~AudioBuffers () +void +AudioBuffers::deallocate () { for (int i = 0; i < _channels; ++i) { free (_data[i]); @@ -112,13 +111,21 @@ AudioBuffers::data (int c) const } /** Set the number of frames that these AudioBuffers will report themselves - * as having. + * as having. If we reduce the number of frames, the `lost' frames will + * be silenced. * @param f Frames; must be less than or equal to the number of allocated frames. */ void AudioBuffers::set_frames (int f) { assert (f <= _allocated_frames); + + for (int c = 0; c < _channels; ++c) { + for (int i = f; i < _frames; ++i) { + _data[c][i] = 0; + } + } + _frames = f; } @@ -144,6 +151,18 @@ AudioBuffers::make_silent (int c) } } +void +AudioBuffers::make_silent (int from, int frames) +{ + assert ((from + frames) <= _allocated_frames); + + for (int c = 0; c < _channels; ++c) { + for (int i = from; i < (from + frames); ++i) { + _data[c][i] = 0; + } + } +} + /** Copy data from another AudioBuffers to this one. All channels are copied. * @param from AudioBuffers to copy from; must have the same number of channels as this. * @param frames_to_copy Number of frames to copy. @@ -184,7 +203,7 @@ AudioBuffers::move (int from, int to, int frames) assert (frames > 0); assert (frames <= _frames); assert ((from + frames) <= _frames); - assert ((to + frames) <= _frames); + assert ((to + frames) <= _allocated_frames); for (int i = 0; i < _channels; ++i) { memmove (_data[i] + to, _data[i] + from, frames * sizeof(float)); @@ -197,6 +216,7 @@ AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, i { int const N = frames (); assert (from->frames() == N); + assert (to_channel <= _channels); float* s = from->data (from_channel); float* d = _data[to_channel]; @@ -241,3 +261,15 @@ AudioBuffers::accumulate_frames (AudioBuffers const * from, int read_offset, int } } +/** @param dB gain in dB */ +void +AudioBuffers::apply_gain (float dB) +{ + float const linear = pow (10, dB / 20); + + for (int i = 0; i < _channels; ++i) { + for (int j = 0; j < _frames; ++j) { + _data[i][j] *= linear; + } + } +}