- if (_resampler) {
- data = _resampler->run (data);
- }
-
- if (_processor) {
- data = _processor->run (data);
- }
-
- Frame const frame_rate = _audio_content->resampled_audio_frame_rate ();
-
- if (_seek_reference) {
- /* We've had an accurate seek and now we're seeing some data */
- ContentTime const delta = time - _seek_reference.get ();
- Frame const delta_frames = delta.frames (frame_rate);
- if (delta_frames > 0) {
- /* This data comes after the seek time. Pad the data with some silence. */
- shared_ptr<AudioBuffers> padded (new AudioBuffers (data->channels(), data->frames() + delta_frames));
- padded->make_silent ();
- padded->copy_from (data.get(), data->frames(), 0, delta_frames);
- data = padded;
- time -= delta;
- } else if (delta_frames < 0) {
- /* This data comes before the seek time. Throw some data away */
- Frame const to_discard = min (-delta_frames, static_cast<Frame> (data->frames()));
- Frame const to_keep = data->frames() - to_discard;
- if (to_keep == 0) {
- /* We have to throw all this data away, so keep _seek_reference and
- try again next time some data arrives.
- */
- return;
- }
- shared_ptr<AudioBuffers> trimmed (new AudioBuffers (data->channels(), to_keep));
- trimmed->copy_from (data.get(), to_keep, to_discard, 0);
- data = trimmed;
- time += ContentTime::from_frames (to_discard, frame_rate);
- }
- _seek_reference = optional<ContentTime> ();
- }
-
- if (!_audio_position) {
- _audio_position = time.frames (frame_rate);
- }
-
- DCPOMATIC_ASSERT (_audio_position.get() >= (_decoded_audio.frame + _decoded_audio.audio->frames()));
-
- add (data);
-}
-
-void
-AudioDecoder::add (shared_ptr<const AudioBuffers> data)
-{
- if (!_audio_position) {
- /* This should only happen when there is a seek followed by a flush, but
- we need to cope with it.
- */
- return;
- }
-
- /* Resize _decoded_audio to fit the new data */
- int new_size = 0;
- if (_decoded_audio.audio->frames() == 0) {
- /* There's nothing in there, so just store the new data */
- new_size = data->frames ();
- _decoded_audio.frame = _audio_position.get ();
- } else {
- /* Otherwise we need to extend _decoded_audio to include the new stuff */
- new_size = _audio_position.get() + data->frames() - _decoded_audio.frame;
- }
-
- _decoded_audio.audio->ensure_size (new_size);
- _decoded_audio.audio->set_frames (new_size);
-
- /* Copy new data in */
- _decoded_audio.audio->copy_from (data.get(), data->frames(), 0, _audio_position.get() - _decoded_audio.frame);
- _audio_position = _audio_position.get() + data->frames ();
-
- /* Limit the amount of data we keep in case nobody is asking for it */
- int const max_frames = _audio_content->resampled_audio_frame_rate () * 10;
- if (_decoded_audio.audio->frames() > max_frames) {
- int const to_remove = _decoded_audio.audio->frames() - max_frames;
- _decoded_audio.frame += to_remove;
- _decoded_audio.audio->move (to_remove, 0, max_frames);
- _decoded_audio.audio->set_frames (max_frames);
- }