summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-03-01 11:36:17 +0000
committerCarl Hetherington <cth@carlh.net>2017-04-19 23:04:32 +0100
commitdc78a40b0c7ce4569874fd1e77a86df907937d50 (patch)
tree3167c3a9f047d3b5af1c5aefc7b8640f4adbf4d9 /src/lib
parent20fb703d5298c0376f1fe7c724cdc9625172e4d0 (diff)
Restore upmixer_a_test and fix resampler flushing.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/player.cc116
-rw-r--r--src/lib/player.h4
-rw-r--r--src/lib/resampler.cc4
-rw-r--r--src/lib/resampler.h2
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: