diff options
| author | Carl Hetherington <cth@carlh.net> | 2017-03-01 11:36:17 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2017-04-19 23:04:32 +0100 |
| commit | dc78a40b0c7ce4569874fd1e77a86df907937d50 (patch) | |
| tree | 3167c3a9f047d3b5af1c5aefc7b8640f4adbf4d9 /src/lib | |
| parent | 20fb703d5298c0376f1fe7c724cdc9625172e4d0 (diff) | |
Restore upmixer_a_test and fix resampler flushing.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/player.cc | 116 | ||||
| -rw-r--r-- | src/lib/player.h | 4 | ||||
| -rw-r--r-- | src/lib/resampler.cc | 4 | ||||
| -rw-r--r-- | src/lib/resampler.h | 2 |
4 files changed, 82 insertions, 44 deletions
diff --git a/src/lib/player.cc b/src/lib/player.cc index c14b55be0..076bd61bc 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -554,6 +554,12 @@ Player::pass () } earliest->done = earliest->decoder->pass (); + if (earliest->done && earliest->content->audio) { + /* Flush the Player audio system for this piece */ + BOOST_FOREACH (AudioStreamPtr i, earliest->content->audio->streams()) { + audio_flush (earliest, i); + } + } /* Emit any audio that is ready */ @@ -668,52 +674,37 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video) } void -Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_audio) +Player::audio_flush (shared_ptr<Piece> piece, AudioStreamPtr stream) { - shared_ptr<Piece> piece = wp.lock (); - if (!piece) { - return; - } - shared_ptr<AudioContent> content = piece->content->audio; DCPOMATIC_ASSERT (content); + shared_ptr<Resampler> r = resampler (content, stream); + pair<shared_ptr<const AudioBuffers>, Frame> ro = r->flush (); + ContentAudio content_audio; + content_audio.audio = ro.first; + content_audio.frame = ro.second; + + /* Compute time in the DCP */ + DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0); + + audio_transform (content, stream, content_audio, time); +} + +/** Do our common processing on some audio */ +void +Player::audio_transform (shared_ptr<AudioContent> content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time) +{ /* Gain */ + if (content->gain() != 0) { shared_ptr<AudioBuffers> gain (new AudioBuffers (content_audio.audio)); gain->apply_gain (content->gain ()); content_audio.audio = gain; } - /* Resample */ - if (stream->frame_rate() != content->resampled_frame_rate()) { - shared_ptr<Resampler> r = resampler (content, stream, true); - pair<shared_ptr<const AudioBuffers>, Frame> ro = r->run (content_audio.audio, content_audio.frame); - content_audio.audio = ro.first; - content_audio.frame = ro.second; - } - - /* XXX: end-trimming used to be checked here */ - - /* Compute time in the DCP */ - DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0); + /* Remap */ - /* Remove anything that comes before the start of the content */ - if (time < piece->content->position()) { - DCPTime const discard_time = piece->content->position() - time; - Frame discard_frames = discard_time.frames_round(_film->audio_frame_rate()); - Frame remaining_frames = content_audio.audio->frames() - discard_frames; - if (remaining_frames <= 0) { - /* This audio is entirely discarded */ - return; - } - shared_ptr<AudioBuffers> cut (new AudioBuffers (content_audio.audio->channels(), remaining_frames)); - cut->copy_from (content_audio.audio.get(), remaining_frames, discard_frames, 0); - content_audio.audio = cut; - time += discard_time; - } - - /* Remap channels */ shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), content_audio.audio->frames())); dcp_mapped->make_silent (); @@ -733,17 +724,62 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a content_audio.audio = dcp_mapped; + /* Process */ + if (_audio_processor) { content_audio.audio = _audio_processor->run (content_audio.audio, _film->audio_channels ()); } - _audio_merger.push (content_audio.audio, time); + /* Push */ + _audio_merger.push (content_audio.audio, time); DCPOMATIC_ASSERT (_stream_states.find (stream) != _stream_states.end ()); _stream_states[stream].last_push_end = time + DCPTime::from_frames (content_audio.audio->frames(), _film->audio_frame_rate()); } void +Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_audio) +{ + shared_ptr<Piece> piece = wp.lock (); + if (!piece) { + return; + } + + shared_ptr<AudioContent> content = piece->content->audio; + DCPOMATIC_ASSERT (content); + + /* Resample */ + if (stream->frame_rate() != content->resampled_frame_rate()) { + shared_ptr<Resampler> r = resampler (content, stream); + pair<shared_ptr<const AudioBuffers>, Frame> ro = r->run (content_audio.audio, content_audio.frame); + content_audio.audio = ro.first; + content_audio.frame = ro.second; + } + + /* XXX: end-trimming used to be checked here */ + + /* Compute time in the DCP */ + DCPTime time = resampled_audio_to_dcp (piece, content_audio.frame) + DCPTime::from_seconds (content->delay() / 1000.0); + + /* Remove anything that comes before the start of the content */ + if (time < piece->content->position()) { + DCPTime const discard_time = piece->content->position() - time; + Frame discard_frames = discard_time.frames_round(_film->audio_frame_rate()); + Frame remaining_frames = content_audio.audio->frames() - discard_frames; + if (remaining_frames <= 0) { + /* This audio is entirely discarded */ + return; + } + shared_ptr<AudioBuffers> cut (new AudioBuffers (content_audio.audio->channels(), remaining_frames)); + cut->copy_from (content_audio.audio.get(), remaining_frames, discard_frames, 0); + content_audio.audio = cut; + time += discard_time; + } + + audio_transform (content, stream, content_audio, time); +} + +void Player::image_subtitle (weak_ptr<Piece> wp, ContentImageSubtitle subtitle) { shared_ptr<Piece> piece = wp.lock (); @@ -821,6 +857,10 @@ Player::text_subtitle (weak_ptr<Piece> wp, ContentTextSubtitle subtitle) void Player::seek (DCPTime time, bool accurate) { + if (_audio_processor) { + _audio_processor->flush (); + } + BOOST_FOREACH (shared_ptr<Piece> i, _pieces) { if (i->content->position() <= time && time < i->content->end()) { i->decoder->seek (dcp_to_content_time (i, time), accurate); @@ -836,17 +876,13 @@ Player::seek (DCPTime time, bool accurate) } shared_ptr<Resampler> -Player::resampler (shared_ptr<const AudioContent> content, AudioStreamPtr stream, bool create) +Player::resampler (shared_ptr<const AudioContent> content, AudioStreamPtr stream) { ResamplerMap::const_iterator i = _resamplers.find (make_pair (content, stream)); if (i != _resamplers.end ()) { return i->second; } - if (!create) { - return shared_ptr<Resampler> (); - } - LOG_GENERAL ( "Creating new resampler from %1 to %2 with %3 channels", stream->frame_rate(), diff --git a/src/lib/player.h b/src/lib/player.h index c10f7adaa..dd7c5dfa1 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -106,10 +106,12 @@ private: void audio (boost::weak_ptr<Piece>, AudioStreamPtr, ContentAudio); void image_subtitle (boost::weak_ptr<Piece>, ContentImageSubtitle); void text_subtitle (boost::weak_ptr<Piece>, ContentTextSubtitle); - boost::shared_ptr<Resampler> resampler (boost::shared_ptr<const AudioContent> content, AudioStreamPtr stream, bool create); + boost::shared_ptr<Resampler> resampler (boost::shared_ptr<const AudioContent> content, AudioStreamPtr stream); DCPTime one_video_frame () const; void fill_video (DCPTimePeriod period); void fill_audio (DCPTimePeriod period); + void audio_flush (boost::shared_ptr<Piece>, AudioStreamPtr stream); + void audio_transform (boost::shared_ptr<AudioContent> content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time); boost::shared_ptr<const Film> _film; boost::shared_ptr<const Playlist> _playlist; diff --git a/src/lib/resampler.cc b/src/lib/resampler.cc index d08e7bc38..1a0c6073d 100644 --- a/src/lib/resampler.cc +++ b/src/lib/resampler.cc @@ -160,7 +160,7 @@ Resampler::run (shared_ptr<const AudioBuffers> in, Frame frame) return make_pair (resampled, out_frame); } -shared_ptr<const AudioBuffers> +pair<shared_ptr<const AudioBuffers>, Frame> Resampler::flush () { shared_ptr<AudioBuffers> out (new AudioBuffers (_channels, 0)); @@ -198,5 +198,5 @@ Resampler::flush () out->set_frames (out_offset); delete[] buffer; - return out; + return make_pair (out, _next_out.get ()); } diff --git a/src/lib/resampler.h b/src/lib/resampler.h index 359598b12..9d620b962 100644 --- a/src/lib/resampler.h +++ b/src/lib/resampler.h @@ -32,7 +32,7 @@ public: ~Resampler (); std::pair<boost::shared_ptr<const AudioBuffers>, Frame> run (boost::shared_ptr<const AudioBuffers>, Frame); - boost::shared_ptr<const AudioBuffers> flush (); + std::pair<boost::shared_ptr<const AudioBuffers>, Frame> flush (); void set_fast (); private: |
