+ shared_ptr<Piece> piece = weak_piece.lock ();
+ if (!piece) {
+ return;
+ }
+
+ shared_ptr<AudioContent> content = dynamic_pointer_cast<AudioContent> (piece->content);
+ assert (content);
+
+ /* Resample */
+ if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
+ shared_ptr<Resampler> r = resampler (content);
+ audio = r->run (audio);
+ }
+
+ /* Remap channels */
+ shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->dcp_audio_channels(), audio->frames()));
+ dcp_mapped->make_silent ();
+ list<pair<int, libdcp::Channel> > map = content->audio_mapping().content_to_dcp ();
+ for (list<pair<int, libdcp::Channel> >::iterator i = map.begin(); i != map.end(); ++i) {
+ if (i->first < audio->channels() && i->second < dcp_mapped->channels()) {
+ dcp_mapped->accumulate_channel (audio.get(), i->first, i->second);
+ }
+ }
+
+ audio = dcp_mapped;
+
+ Time time = content->start() + (frame * TIME_HZ / _film->dcp_audio_frame_rate()) + (content->audio_delay() * TIME_HZ / 1000);
+
+ /* We must cut off anything that comes before the start of all time */
+ if (time < 0) {
+ int const frames = - time * _film->dcp_audio_frame_rate() / TIME_HZ;
+ if (frames >= audio->frames ()) {
+ return;
+ }
+
+ shared_ptr<AudioBuffers> trimmed (new AudioBuffers (audio->channels(), audio->frames() - frames));
+ trimmed->copy_from (audio.get(), audio->frames() - frames, frames, 0);
+
+ audio = trimmed;
+ time = 0;
+ }
+
+ /* The time of this audio may indicate that some of our buffered audio is not going to
+ be added to any more, so it can be emitted.
+ */
+
+ if (time > _audio_position) {
+ /* We can emit some audio from our buffers */
+ OutputAudioFrame const N = _film->time_to_audio_frames (time - _audio_position);
+ if (N > _audio_buffers.frames()) {
+ /* We need some extra silence before whatever is in the buffers */
+ _audio_buffers.ensure_size (N);
+ _audio_buffers.move (0, N - _audio_buffers.frames(), _audio_buffers.frames ());
+ _audio_buffers.make_silent (0, _audio_buffers.frames());
+ _audio_buffers.set_frames (N);
+ }
+
+ if (N > _audio_buffers.frames()) {
+ cout << "N=" << N << ", ab=" << _audio_buffers.frames() << "\n";
+ }
+ assert (N <= _audio_buffers.frames());
+ shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
+ emit->copy_from (&_audio_buffers, N, 0, 0);
+ Audio (emit, _audio_position);
+ _audio_position = piece->audio_position = time + _film->audio_frames_to_time (N);
+
+ /* And remove it from our buffers */
+ if (_audio_buffers.frames() > N) {
+ _audio_buffers.move (N, 0, _audio_buffers.frames() - N);
+ }
+ _audio_buffers.set_frames (_audio_buffers.frames() - N);
+ }
+
+ /* Now accumulate the new audio into our buffers */
+ _audio_buffers.ensure_size (_audio_buffers.frames() + audio->frames());
+ _audio_buffers.accumulate_frames (audio.get(), 0, 0, audio->frames ());
+ _audio_buffers.set_frames (_audio_buffers.frames() + audio->frames());