summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-25 13:26:40 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-25 13:26:40 +0100
commitd9362bdd24f01e4c833e89d63ac3816f36eae36e (patch)
treee1355acbfad222fb14ec386b14dcddce0b212bb5 /src/lib
parentfd970b185e9357522f5d12d62800df8769764729 (diff)
Move resampling back into AudioDecoder and fix various screw-ups with audio in the player.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_decoder.cc23
-rw-r--r--src/lib/audio_decoder.h5
-rw-r--r--src/lib/ffmpeg_decoder.cc2
-rw-r--r--src/lib/job.cc9
-rw-r--r--src/lib/job.h2
-rw-r--r--src/lib/player.cc49
-rw-r--r--src/lib/player.h4
-rw-r--r--src/lib/sndfile_decoder.cc2
8 files changed, 43 insertions, 53 deletions
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc
index 59c631632..0ed3505cf 100644
--- a/src/lib/audio_decoder.cc
+++ b/src/lib/audio_decoder.cc
@@ -21,6 +21,7 @@
#include "audio_buffers.h"
#include "exceptions.h"
#include "log.h"
+#include "resampler.h"
#include "i18n.h"
@@ -31,16 +32,30 @@ using std::cout;
using boost::optional;
using boost::shared_ptr;
-AudioDecoder::AudioDecoder (shared_ptr<const Film> f)
- : Decoder (f)
+AudioDecoder::AudioDecoder (shared_ptr<const Film> film, shared_ptr<const AudioContent> content)
+ : Decoder (film)
, _audio_position (0)
{
-
+ if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
+ _resampler.reset (
+ new Resampler (
+ content->content_audio_frame_rate(),
+ content->output_audio_frame_rate(),
+ content->audio_channels()
+ )
+ );
+ }
}
void
AudioDecoder::audio (shared_ptr<const AudioBuffers> data, AudioContent::Frame frame)
{
- Audio (data, frame);
+ /* XXX: no-one's calling _resampler->flush() again */
+
+ if (_resampler) {
+ data = _resampler->run (data);
+ }
+
+ Audio (data, _audio_position);
_audio_position = frame + data->frames ();
}
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index 2ad53da8b..b1ec54a7b 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -29,6 +29,7 @@
#include "audio_content.h"
class AudioBuffers;
+class Resampler;
/** @class AudioDecoder.
* @brief Parent class for audio decoders.
@@ -36,7 +37,7 @@ class AudioBuffers;
class AudioDecoder : public virtual Decoder
{
public:
- AudioDecoder (boost::shared_ptr<const Film>);
+ AudioDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const AudioContent>);
/** Emitted when some audio data is ready */
boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>, AudioContent::Frame)> Audio;
@@ -44,7 +45,9 @@ public:
protected:
void audio (boost::shared_ptr<const AudioBuffers>, AudioContent::Frame);
+ /** Frame index of next emission (post resampling) */
AudioContent::Frame _audio_position;
+ boost::shared_ptr<Resampler> _resampler;
};
#endif
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 8329cad65..d8319723a 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -60,7 +60,7 @@ using libdcp::Size;
FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegContent> c, bool video, bool audio)
: Decoder (f)
, VideoDecoder (f, c)
- , AudioDecoder (f)
+ , AudioDecoder (f, c)
, SubtitleDecoder (f)
, FFmpeg (c)
, _subtitle_codec_context (0)
diff --git a/src/lib/job.cc b/src/lib/job.cc
index e63ea6dc8..12dc88fbc 100644
--- a/src/lib/job.cc
+++ b/src/lib/job.cc
@@ -34,6 +34,7 @@
using std::string;
using std::list;
+using std::cout;
using std::stringstream;
using boost::shared_ptr;
@@ -43,6 +44,7 @@ Job::Job (shared_ptr<const Film> f)
, _state (NEW)
, _start_time (0)
, _progress_unknown (false)
+ , _last_set (0)
, _ran_for (0)
{
descend (1);
@@ -213,6 +215,13 @@ Job::elapsed_time () const
void
Job::set_progress (float p)
{
+ if (fabs (p - _last_set) < 0.01) {
+ /* Calm excessive progress reporting */
+ return;
+ }
+
+ _last_set = p;
+
boost::mutex::scoped_lock lm (_progress_mutex);
_progress_unknown = false;
_stack.back().normalised = p;
diff --git a/src/lib/job.h b/src/lib/job.h
index 343d40095..eb09ba386 100644
--- a/src/lib/job.h
+++ b/src/lib/job.h
@@ -126,6 +126,8 @@ private:
/** true if this job's progress will always be unknown */
bool _progress_unknown;
+ float _last_set;
+
int _ran_for;
};
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 8cc1849e8..1ab164d86 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -31,7 +31,6 @@
#include "job.h"
#include "image.h"
#include "ratio.h"
-#include "resampler.h"
#include "log.h"
#include "scaler.h"
@@ -191,18 +190,6 @@ Player::pass ()
cout << "Pass " << *earliest << "\n";
#endif
earliest->decoder->pass ();
-
- if (earliest->decoder->done()) {
- shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (earliest->content);
- assert (ac);
- shared_ptr<Resampler> re = resampler (ac, false);
- if (re) {
- shared_ptr<const AudioBuffers> b = re->flush ();
- if (b->frames ()) {
- process_audio (earliest, b, ac->audio_length ());
- }
- }
- }
}
break;
}
@@ -277,12 +264,6 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers
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, true);
- audio = r->run (audio);
- }
-
/* Remap channels */
shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames()));
dcp_mapped->make_silent ();
@@ -295,10 +276,9 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers
audio = dcp_mapped;
- /* Convert frame to time. After resampling, the frame time (in the DCP rate) will be T_D where
- T_D = frame * DCP_rate / original_rate. Hence the time in seconds is T_D / DCP_rate.
- */
- Time time = content->start() + (frame * TIME_HZ / _film->audio_frame_rate()) + (content->audio_delay() * TIME_HZ / 1000);
+ Time time = content->start()
+ + _film->audio_frames_to_time (frame)
+ + (content->audio_delay() * TIME_HZ / 1000);
/* We must cut off anything that comes before the start of all time */
if (time < 0) {
@@ -319,7 +299,7 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers
*/
if (time > _audio_position) {
- /* We can emit some audio from our buffers */
+ /* We can emit some audio from our buffers; this is how many frames */
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 */
@@ -329,10 +309,12 @@ Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers
_audio_buffers.set_frames (N);
}
assert (N <= _audio_buffers.frames());
+
+ /* XXX: not convinced that a copy is necessary here */
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);
+ _audio_position = piece->audio_position = _audio_position + _film->audio_frames_to_time (N);
/* And remove it from our buffers */
if (_audio_buffers.frames() > N) {
@@ -515,23 +497,6 @@ Player::set_video_container_size (libdcp::Size s)
_black_frame->make_black ();
}
-shared_ptr<Resampler>
-Player::resampler (shared_ptr<AudioContent> c, bool create)
-{
- map<shared_ptr<AudioContent>, shared_ptr<Resampler> >::iterator i = _resamplers.find (c);
- if (i != _resamplers.end ()) {
- return i->second;
- }
-
- if (!create) {
- return shared_ptr<Resampler> ();
- }
-
- shared_ptr<Resampler> r (new Resampler (c->content_audio_frame_rate(), c->output_audio_frame_rate(), c->audio_channels()));
- _resamplers[c] = r;
- return r;
-}
-
void
Player::emit_black ()
{
diff --git a/src/lib/player.h b/src/lib/player.h
index baaa85791..5b1b6936b 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -35,7 +35,6 @@ class Playlist;
class AudioContent;
class Piece;
class Image;
-class Resampler;
/** @class Player
* @brief A class which can `play' a Playlist; emitting its audio and video.
@@ -90,7 +89,6 @@ private:
void flush ();
void emit_black ();
void emit_silence (OutputAudioFrame);
- boost::shared_ptr<Resampler> resampler (boost::shared_ptr<AudioContent>, bool);
void film_changed (Film::Property);
void update_subtitle ();
@@ -113,8 +111,6 @@ private:
libdcp::Size _video_container_size;
boost::shared_ptr<Image> _black_frame;
- std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers;
- boost::shared_ptr<Resampler> _last_resampler;
struct {
boost::weak_ptr<Piece> piece;
diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc
index 1fc1ecaf2..09ccf4fbc 100644
--- a/src/lib/sndfile_decoder.cc
+++ b/src/lib/sndfile_decoder.cc
@@ -35,7 +35,7 @@ using boost::shared_ptr;
SndfileDecoder::SndfileDecoder (shared_ptr<const Film> f, shared_ptr<const SndfileContent> c)
: Decoder (f)
- , AudioDecoder (f)
+ , AudioDecoder (f, c)
, _sndfile_content (c)
, _deinterleave_buffer (0)
{