From 40b3ced17b7fff8badfaa8ec2201a8186cdc7dc2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 2 May 2014 18:17:35 +0100 Subject: [PATCH] Rename AudioContent frame_rate methods and move resampled_audio_frame_rate into AudioContent. --- src/lib/audio_content.cc | 34 ++++++++++++++++++++++++++++++---- src/lib/audio_content.h | 5 +++-- src/lib/audio_decoder.cc | 8 ++++---- src/lib/ffmpeg_content.cc | 25 +------------------------ src/lib/ffmpeg_content.h | 3 +-- src/lib/player.cc | 2 +- src/lib/sndfile_content.cc | 15 +++------------ src/lib/sndfile_content.h | 4 +--- src/lib/sndfile_decoder.cc | 2 +- src/wx/audio_panel.cc | 2 +- test/audio_decoder_test.cc | 18 +++++++----------- test/frame_rate_test.cc | 20 ++++++++++---------- 12 files changed, 63 insertions(+), 75 deletions(-) diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index c84f57130..d9e00ff14 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Carl Hetherington + Copyright (C) 2013-2014 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -150,11 +150,11 @@ string AudioContent::technical_summary () const { return String::compose ( - "audio: channels %1, length %2, raw rate %3, out rate %4", + "audio: channels %1, length %2, content rate %3, resampled rate %4", audio_channels(), audio_length().seconds(), - content_audio_frame_rate(), - output_audio_frame_rate() + audio_frame_rate(), + resampled_audio_frame_rate() ); } @@ -163,3 +163,29 @@ AudioContent::set_audio_mapping (AudioMapping) { signal_changed (AudioContentProperty::AUDIO_MAPPING); } + +/** @return the frame rate that this content should be resampled to in order + * that it is in sync with the active video content at its start time. + */ +int +AudioContent::resampled_audio_frame_rate () const +{ + shared_ptr film = _film.lock (); + assert (film); + + /* Resample to a DCI-approved sample rate */ + double t = dcp_audio_frame_rate (audio_frame_rate ()); + + FrameRateChange frc = film->active_frame_rate_change (position ()); + + /* Compensate if the DCP is being run at a different frame rate + to the source; that is, if the video is run such that it will + look different in the DCP compared to the source (slower or faster). + */ + + if (frc.change_speed) { + t /= frc.speed_up; + } + + return rint (t); +} diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 60d53b343..09f90b85c 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -63,12 +63,13 @@ public: /** @return the length of the audio in the content */ virtual ContentTime audio_length () const = 0; /** @return the frame rate of the content */ - virtual int content_audio_frame_rate () const = 0; - virtual int output_audio_frame_rate () const = 0; + virtual int audio_frame_rate () const = 0; virtual AudioMapping audio_mapping () const = 0; virtual void set_audio_mapping (AudioMapping); virtual boost::filesystem::path audio_analysis_path () const; + int resampled_audio_frame_rate () const; + boost::signals2::connection analyse_audio (boost::function); void set_audio_gain (float); diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc index f914ecf8a..4a543cea9 100644 --- a/src/lib/audio_decoder.cc +++ b/src/lib/audio_decoder.cc @@ -39,8 +39,8 @@ using boost::shared_ptr; AudioDecoder::AudioDecoder (shared_ptr content) : _audio_content (content) { - if (content->output_audio_frame_rate() != content->content_audio_frame_rate() && content->audio_channels ()) { - _resampler.reset (new Resampler (content->content_audio_frame_rate(), content->output_audio_frame_rate(), content->audio_channels ())); + if (content->resampled_audio_frame_rate() != content->audio_frame_rate() && content->audio_channels ()) { + _resampler.reset (new Resampler (content->audio_frame_rate(), content->resampled_audio_frame_rate(), content->audio_channels ())); } reset_decoded_audio (); @@ -61,7 +61,7 @@ AudioDecoder::get_audio (AudioFrame frame, AudioFrame length, bool accurate) if (frame < _decoded_audio.frame || end > (_decoded_audio.frame + length * 4)) { /* Either we have no decoded data, or what we do have is a long way from what we want: seek */ - seek (ContentTime::from_frames (frame, _audio_content->content_audio_frame_rate()), accurate); + seek (ContentTime::from_frames (frame, _audio_content->audio_frame_rate()), accurate); } /* Offset of the data that we want from the start of _decoded_audio.audio @@ -126,7 +126,7 @@ AudioDecoder::audio (shared_ptr data, ContentTime time) } if (!_audio_position) { - _audio_position = time.frames (_audio_content->output_audio_frame_rate ()); + _audio_position = time.frames (_audio_content->resampled_audio_frame_rate ()); } assert (_audio_position.get() >= (_decoded_audio.frame + _decoded_audio.audio->frames())); diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 4e14802e8..a51cb3de8 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -288,7 +288,7 @@ FFmpegContent::audio_channels () const } int -FFmpegContent::content_audio_frame_rate () const +FFmpegContent::audio_frame_rate () const { boost::mutex::scoped_lock lm (_mutex); @@ -299,29 +299,6 @@ FFmpegContent::content_audio_frame_rate () const return _audio_stream->frame_rate; } -int -FFmpegContent::output_audio_frame_rate () const -{ - shared_ptr film = _film.lock (); - assert (film); - - /* Resample to a DCI-approved sample rate */ - double t = dcp_audio_frame_rate (content_audio_frame_rate ()); - - FrameRateChange frc (video_frame_rate(), film->video_frame_rate()); - - /* Compensate if the DCP is being run at a different frame rate - to the source; that is, if the video is run such that it will - look different in the DCP compared to the source (slower or faster). - */ - - if (frc.change_speed) { - t /= frc.speed_up; - } - - return rint (t); -} - bool operator== (FFmpegStream const & a, FFmpegStream const & b) { diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index d86c90af9..1ab0a92d0 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -146,8 +146,7 @@ public: /* AudioContent */ int audio_channels () const; ContentTime audio_length () const; - int content_audio_frame_rate () const; - int output_audio_frame_rate () const; + int audio_frame_rate () const; AudioMapping audio_mapping () const; void set_audio_mapping (AudioMapping); boost::filesystem::path audio_analysis_path () const; diff --git a/src/lib/player.cc b/src/lib/player.cc index 5fe35e34d..75b550093 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -439,7 +439,7 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) shared_ptr decoder = dynamic_pointer_cast ((*i)->decoder); assert (decoder); - if (content->content_audio_frame_rate() == 0) { + if (content->audio_frame_rate() == 0) { /* This AudioContent has no audio (e.g. if it is an FFmpegContent with no * audio stream). */ diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 5b408f2da..0cf65967f 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -80,8 +80,8 @@ SndfileContent::information () const s << String::compose ( _("%1 channels, %2kHz, %3 samples"), audio_channels(), - content_audio_frame_rate() / 1000.0, - audio_length().frames (content_audio_frame_rate ()) + audio_frame_rate() / 1000.0, + audio_length().frames (audio_frame_rate ()) ); return s.str (); @@ -134,7 +134,7 @@ SndfileContent::as_xml (xmlpp::Node* node) const node->add_child("AudioChannels")->add_child_text (lexical_cast (audio_channels ())); node->add_child("AudioLength")->add_child_text (lexical_cast (audio_length().get ())); - node->add_child("AudioFrameRate")->add_child_text (lexical_cast (content_audio_frame_rate ())); + node->add_child("AudioFrameRate")->add_child_text (lexical_cast (audio_frame_rate ())); _audio_mapping.as_xml (node->add_child("AudioMapping")); } @@ -146,15 +146,6 @@ SndfileContent::full_length () const return DCPTime (audio_length(), film->active_frame_rate_change (position ())); } -int -SndfileContent::output_audio_frame_rate () const -{ - shared_ptr film = _film.lock (); - assert (film); - - return film->audio_frame_rate (); -} - void SndfileContent::set_audio_mapping (AudioMapping m) { diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 04d157131..bbc5111ff 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -57,13 +57,11 @@ public: return _audio_length; } - int content_audio_frame_rate () const { + int audio_frame_rate () const { boost::mutex::scoped_lock lm (_mutex); return _audio_frame_rate; } - int output_audio_frame_rate () const; - AudioMapping audio_mapping () const { boost::mutex::scoped_lock lm (_mutex); return _audio_mapping; diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc index c37a84474..602014d58 100644 --- a/src/lib/sndfile_decoder.cc +++ b/src/lib/sndfile_decoder.cc @@ -74,7 +74,7 @@ SndfileDecoder::pass () /* Do things in half second blocks as I think there may be limits to what FFmpeg (and in particular the resampler) can cope with. */ - sf_count_t const block = _sndfile_content->content_audio_frame_rate() / 2; + sf_count_t const block = _sndfile_content->audio_frame_rate() / 2; sf_count_t const this_time = min (block, _remaining); int const channels = _sndfile_content->audio_channels (); diff --git a/src/wx/audio_panel.cc b/src/wx/audio_panel.cc index 1c679d336..eb95e17ab 100644 --- a/src/wx/audio_panel.cc +++ b/src/wx/audio_panel.cc @@ -237,7 +237,7 @@ AudioPanel::setup_stream_description () } else { s << fcs->audio_channels() << wxT (" ") << _("channels"); } - s << wxT (", ") << fcs->content_audio_frame_rate() << _("Hz"); + s << wxT (", ") << fcs->audio_frame_rate() << _("Hz"); _description->SetLabel (s); } } diff --git a/test/audio_decoder_test.cc b/test/audio_decoder_test.cc index 46f9d5ac6..a14e2f9be 100644 --- a/test/audio_decoder_test.cc +++ b/test/audio_decoder_test.cc @@ -44,7 +44,7 @@ public: { AudioFrame const N = min ( AudioFrame (2000), - _audio_content->audio_length().frames (_audio_content->output_audio_frame_rate ()) - _position + _audio_content->audio_length().frames (_audio_content->resampled_audio_frame_rate ()) - _position ); shared_ptr buffers (new AudioBuffers (_audio_content->audio_channels(), N)); @@ -54,7 +54,7 @@ public: } } - audio (buffers, ContentTime::from_frames (_position, _audio_content->output_audio_frame_rate ())); + audio (buffers, ContentTime::from_frames (_position, _audio_content->resampled_audio_frame_rate ())); _position += N; return N < 2000; @@ -63,7 +63,7 @@ public: void seek (ContentTime t, bool accurate) { AudioDecoder::seek (t, accurate); - _position = t.frames (_audio_content->output_audio_frame_rate ()); + _position = t.frames (_audio_content->resampled_audio_frame_rate ()); } private: @@ -98,11 +98,7 @@ public: return ContentTime::from_seconds (61.2942); } - int content_audio_frame_rate () const { - return 48000; - } - - int output_audio_frame_rate () const { + int audio_frame_rate () const { return 48000; } @@ -119,7 +115,7 @@ shared_ptr decoder; static shared_ptr get (AudioFrame from, AudioFrame length) { - decoder->seek (ContentTime::from_frames (from, content->output_audio_frame_rate ()), true); + decoder->seek (ContentTime::from_frames (from, content->resampled_audio_frame_rate ()), true); shared_ptr ca = decoder->get_audio (from, length, true); BOOST_CHECK_EQUAL (ca->frame, from); return ca; @@ -152,8 +148,8 @@ BOOST_AUTO_TEST_CASE (audio_decoder_get_audio_test) /* Read off the end */ - AudioFrame const from = content->output_audio_frame_rate() * 61; - AudioFrame const length = content->output_audio_frame_rate() * 4; + AudioFrame const from = content->resampled_audio_frame_rate() * 61; + AudioFrame const length = content->resampled_audio_frame_rate() * 4; shared_ptr ca = get (from, length); for (int i = 0; i < content->audio_channels(); ++i) { diff --git a/test/frame_rate_test.cc b/test/frame_rate_test.cc index e710b0934..f2c46396c 100644 --- a/test/frame_rate_test.cc +++ b/test/frame_rate_test.cc @@ -241,7 +241,7 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) shared_ptr film = new_test_film ("audio_sampling_rate_test"); /* Get any piece of content, it doesn't matter what */ shared_ptr content (new FFmpegContent (film, "test/data/test.mp4")); - film->add_content (content); + film->examine_and_add_content (content); wait_for_jobs (); std::list afr; @@ -253,43 +253,43 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) content->_video_frame_rate = 24; film->set_video_frame_rate (24); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 48000); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 48000); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 48000); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 48000); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 80000, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 96000); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 96000); content->_video_frame_rate = 23.976; film->set_video_frame_rate (24); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 47952); content->_video_frame_rate = 29.97; film->set_video_frame_rate (30); BOOST_CHECK_EQUAL (film->video_frame_rate (), 30); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 47952); content->_video_frame_rate = 25; film->set_video_frame_rate (24); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 48000, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 50000); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 50000); content->_video_frame_rate = 25; film->set_video_frame_rate (24); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 44100, 0))); - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 50000); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 50000); /* Check some out-there conversions (not the best) */ content->_video_frame_rate = 14.99; film->set_video_frame_rate (25); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); - /* The FrameRateChange within output_audio_frame_rate should choose to double-up + /* The FrameRateChange within resampled_audio_frame_rate should choose to double-up the 14.99 fps video to 30 and then run it slow at 25. */ - BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), rint (48000 * 2 * 14.99 / 25)); + BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), rint (48000 * 2 * 14.99 / 25)); } -- 2.30.2