Some missing copy constructors / operator= / noncopyable.
[dcpomatic.git] / src / lib / audio_buffers.cc
index c3e89f1302e5315e01495c374a994975b19b806b..d387304142462c6245b70aace709c730deb669ae 100644 (file)
@@ -30,69 +30,70 @@ 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<float**> (malloc (_channels * sizeof (float *)));
-       if (!_data) {
-               throw bad_alloc ();
-       }
-       
-       for (int i = 0; i < _channels; ++i) {
-               _data[i] = static_cast<float*> (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<float**> (malloc (_channels * sizeof (float *)));
-       if (!_data) {
-               throw bad_alloc ();
-       }
-       
-       for (int i = 0; i < _channels; ++i) {
-               _data[i] = static_cast<float*> (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<const AudioBuffers> 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<float**> (malloc (_channels * sizeof (float *)));
        if (!_data) {
                throw bad_alloc ();
        }
        
        for (int i = 0; i < _channels; ++i) {
-               _data[i] = static_cast<float*> (malloc (_frames * sizeof (float)));
+               _data[i] = static_cast<float*> (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]);
@@ -144,6 +145,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.
@@ -197,6 +210,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];
@@ -206,6 +220,9 @@ AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, i
        }
 }
 
+/** Ensure we have space for at least a certain number of frames.  If we extend
+ *  the buffers, fill the new space with silence.
+ */
 void
 AudioBuffers::ensure_size (int frames)
 {
@@ -218,6 +235,9 @@ AudioBuffers::ensure_size (int frames)
                if (!_data[i]) {
                        throw bad_alloc ();
                }
+               for (int j = _allocated_frames; j < frames; ++j) {
+                       _data[i][j] = 0;
+               }
        }
 
        _allocated_frames = frames;