+
+/** @param c Channel index.
+ * @return AudioBuffers object containing only channel `c' from this AudioBuffers.
+ */
+shared_ptr<AudioBuffers>
+AudioBuffers::channel (int c) const
+{
+ shared_ptr<AudioBuffers> o (new AudioBuffers (1, frames ()));
+ o->copy_channel_from (this, c, 0);
+ return o;
+}
+
+/** Copy all the samples from a channel on another AudioBuffers to a channel on this one.
+ * @param from AudioBuffers to copy from.
+ * @param from_channel Channel index in `from' to copy from.
+ * @param to_channel Channel index in this to copy into, overwriting what's already there.
+ */
+void
+AudioBuffers::copy_channel_from (AudioBuffers const * from, int from_channel, int to_channel)
+{
+ DCPOMATIC_ASSERT (from->frames() == frames());
+ memcpy (data(to_channel), from->data(from_channel), frames() * sizeof (float));
+}
+
+/** Make a copy of these AudioBuffers */
+shared_ptr<AudioBuffers>
+AudioBuffers::clone () const
+{
+ shared_ptr<AudioBuffers> b (new AudioBuffers (channels (), frames ()));
+ b->copy_from (this, frames (), 0, 0);
+ return b;
+}
+
+/** Extend these buffers with the data from another. The AudioBuffers must have the same number of channels. */
+void
+AudioBuffers::append (shared_ptr<const AudioBuffers> other)
+{
+ DCPOMATIC_ASSERT (channels() == other->channels());
+ ensure_size (_frames + other->frames());
+ copy_from (other.get(), other->frames(), 0, _frames);
+ _frames += other->frames();
+}
+
+/** Remove some frames from the start of these AudioBuffers */
+void
+AudioBuffers::trim_start (int32_t frames)
+{
+ DCPOMATIC_ASSERT (frames <= _frames);
+ move (_frames - frames, frames, 0);
+ set_frames (_frames - frames);
+}