- AudioMapping mapping = _film->audio_mapping ();
- if (!_audio_buffers) {
- _audio_buffers.reset (new AudioBuffers (mapping.dcp_channels(), b->frames ()));
- _audio_buffers->make_silent ();
- _audio_time = t;
- if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
- _audio_time = _audio_time.get() + _audio_start[_sequential_audio_decoder];
- }
- }
-
- for (int i = 0; i < b->channels(); ++i) {
- list<libdcp::Channel> dcp = mapping.content_to_dcp (AudioMapping::Channel (c, i));
- for (list<libdcp::Channel>::iterator j = dcp.begin(); j != dcp.end(); ++j) {
- _audio_buffers->accumulate (b, i, static_cast<int> (*j));
- }
- }
-
- if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
- /* We can just emit this audio now as it will all be here */
- Audio (_audio_buffers, t);
- _audio_buffers.reset ();
- _audio_time = boost::none;
- }
+ /* XXX: mapping */
+
+ /* 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 > _last_audio) {
+ /* We can emit some audio from our buffers */
+ OutputAudioFrame const N = min (_film->time_to_audio_frames (time - _last_audio), static_cast<OutputAudioFrame> (_audio_buffers.frames()));
+ shared_ptr<AudioBuffers> emit (new AudioBuffers (_audio_buffers.channels(), N));
+ emit->copy_from (&_audio_buffers, N, 0, 0);
+ Audio (emit, _last_audio);
+ _last_audio += _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 */
+
+ if (_audio_buffers.frames() == 0) {
+ /* We have no remaining data. Emit silence up to the start of this new data */
+ if ((time - _last_audio) > 0) {
+ emit_silence (time - _last_audio);
+ }
+ }
+
+ _audio_buffers.ensure_size (time - _last_audio + audio->frames());
+ _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio));
+ rd->last = time + _film->audio_frames_to_time (audio->frames ());