+ DCPTimePeriod period (time, time + DCPTime::from_frames (audio->frames(), _frame_rate));
+
+ /* Mix any overlapping parts of this new block with existing ones */
+ BOOST_FOREACH (Buffer i, _buffers) {
+ optional<DCPTimePeriod> overlap = i.period().overlap (period);
+ if (overlap) {
+ int32_t const offset = frames(DCPTime(overlap->from - i.time));
+ int32_t const frames_to_mix = frames(overlap->duration());
+ if (i.time < time) {
+ i.audio->accumulate_frames(audio.get(), frames_to_mix, 0, offset);
+ } else {
+ i.audio->accumulate_frames(audio.get(), frames_to_mix, offset, 0);
+ }
+ }
+ }
+
+ list<DCPTimePeriod> periods;
+ BOOST_FOREACH (Buffer i, _buffers) {
+ periods.push_back (i.period ());
+ }
+
+ /* Add the non-overlapping parts */
+ BOOST_FOREACH (DCPTimePeriod i, subtract (period, periods)) {
+ list<Buffer>::iterator before = _buffers.end();
+ list<Buffer>::iterator after = _buffers.end();
+ for (list<Buffer>::iterator j = _buffers.begin(); j != _buffers.end(); ++j) {
+ if (j->period().to == i.from) {
+ before = j;
+ }
+ if (j->period().from == i.to) {
+ after = j;
+ }
+ }
+
+ /* Get the part of audio that we want to use */
+ shared_ptr<AudioBuffers> part (new AudioBuffers (audio->channels(), frames(i.to) - frames(i.from)));
+ part->copy_from (audio.get(), part->frames(), frames(DCPTime(i.from - time)), 0);
+
+ if (before == _buffers.end() && after == _buffers.end()) {
+ /* New buffer */
+ DCPOMATIC_ASSERT (part->frames() > 0);
+ _buffers.push_back (Buffer (part, time, _frame_rate));
+ } else if (before != _buffers.end() && after == _buffers.end()) {
+ /* We have an existing buffer before this one; append new data to it */
+ before->audio->append (part);
+ } else if (before ==_buffers.end() && after != _buffers.end()) {
+ /* We have an existing buffer after this one; append it to the new data and replace */
+ part->append (after->audio);
+ after->audio = part;
+ after->time = time;
+ } else {
+ /* We have existing buffers both before and after; coalesce them all */
+ before->audio->append (part);
+ before->audio->append (after->audio);
+ _buffers.erase (after);
+ }