Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1144)

Unified Diff: media/filters/audio_renderer_algorithm_base.cc

Issue 9826028: Rename AudioRendererBase and AudioRendererAlgorithmBase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Unit tests were somehow unadded Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/audio_renderer_algorithm_base.cc
diff --git a/media/filters/audio_renderer_algorithm_base.cc b/media/filters/audio_renderer_algorithm_base.cc
deleted file mode 100644
index 990c477727e1a8bf09f32f113bb19ffdfd349722..0000000000000000000000000000000000000000
--- a/media/filters/audio_renderer_algorithm_base.cc
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/filters/audio_renderer_algorithm_base.h"
-
-#include <algorithm>
-#include <cmath>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/audio/audio_util.h"
-#include "media/base/buffers.h"
-
-namespace media {
-
-// The starting size in bytes for |audio_buffer_|.
-// Previous usage maintained a deque of 16 Buffers, each of size 4Kb. This
-// worked well, so we maintain this number of bytes (16 * 4096).
-static const int kStartingBufferSizeInBytes = 65536;
-
-// The maximum size in bytes for the |audio_buffer_|. Arbitrarily determined.
-// This number represents 3 seconds of 96kHz/16 bit 7.1 surround sound.
-static const int kMaxBufferSizeInBytes = 4608000;
-
-// Duration of audio segments used for crossfading (in seconds).
-static const double kWindowDuration = 0.08;
-
-// Duration of crossfade between audio segments (in seconds).
-static const double kCrossfadeDuration = 0.008;
-
-// Max/min supported playback rates for fast/slow audio. Audio outside of these
-// ranges are muted.
-// Audio at these speeds would sound better under a frequency domain algorithm.
-static const float kMinPlaybackRate = 0.5f;
-static const float kMaxPlaybackRate = 4.0f;
-
-AudioRendererAlgorithmBase::AudioRendererAlgorithmBase()
- : channels_(0),
- samples_per_second_(0),
- bytes_per_channel_(0),
- playback_rate_(0.0f),
- audio_buffer_(0, kStartingBufferSizeInBytes),
- bytes_in_crossfade_(0),
- bytes_per_frame_(0),
- index_into_window_(0),
- crossfade_frame_number_(0),
- muted_(false),
- needs_more_data_(false),
- window_size_(0) {
-}
-
-AudioRendererAlgorithmBase::~AudioRendererAlgorithmBase() {}
-
-bool AudioRendererAlgorithmBase::ValidateConfig(
- int channels,
- int samples_per_second,
- int bits_per_channel) {
- bool status = true;
-
- if (channels <= 0 || channels > 8) {
- DVLOG(1) << "We only support audio with between 1 and 8 channels.";
- status = false;
- }
-
- if (samples_per_second <= 0 || samples_per_second > 256000) {
- DVLOG(1) << "We only support sample rates between 1 and 256000Hz.";
- status = false;
- }
-
- if (bits_per_channel != 8 && bits_per_channel != 16 &&
- bits_per_channel != 32) {
- DVLOG(1) << "We only support 8, 16, 32 bit audio.";
- status = false;
- }
-
- return status;
-}
-
-void AudioRendererAlgorithmBase::Initialize(
- int channels,
- int samples_per_second,
- int bits_per_channel,
- float initial_playback_rate,
- const base::Closure& callback) {
- DCHECK(!callback.is_null());
- DCHECK(ValidateConfig(channels, samples_per_second, bits_per_channel));
-
- channels_ = channels;
- samples_per_second_ = samples_per_second;
- bytes_per_channel_ = bits_per_channel / 8;
- bytes_per_frame_ = bytes_per_channel_ * channels_;
- request_read_cb_ = callback;
- SetPlaybackRate(initial_playback_rate);
-
- window_size_ =
- samples_per_second_ * bytes_per_channel_ * channels_ * kWindowDuration;
- AlignToFrameBoundary(&window_size_);
-
- bytes_in_crossfade_ =
- samples_per_second_ * bytes_per_channel_ * channels_ * kCrossfadeDuration;
- AlignToFrameBoundary(&bytes_in_crossfade_);
-
- crossfade_buffer_.reset(new uint8[bytes_in_crossfade_]);
-}
-
-int AudioRendererAlgorithmBase::FillBuffer(
- uint8* dest, int requested_frames) {
- DCHECK_NE(bytes_per_frame_, 0);
-
- if (playback_rate_ == 0.0f)
- return 0;
-
- int total_frames_rendered = 0;
- uint8* output_ptr = dest;
- while (total_frames_rendered < requested_frames) {
- if (index_into_window_ == window_size_)
- ResetWindow();
-
- bool rendered_frame = true;
- if (playback_rate_ > 1.0)
- rendered_frame = OutputFasterPlayback(output_ptr);
- else if (playback_rate_ < 1.0)
- rendered_frame = OutputSlowerPlayback(output_ptr);
- else
- rendered_frame = OutputNormalPlayback(output_ptr);
-
- if (!rendered_frame) {
- needs_more_data_ = true;
- break;
- }
-
- output_ptr += bytes_per_frame_;
- total_frames_rendered++;
- }
- return total_frames_rendered;
-}
-
-void AudioRendererAlgorithmBase::ResetWindow() {
- DCHECK_LE(index_into_window_, window_size_);
- index_into_window_ = 0;
- crossfade_frame_number_ = 0;
-}
-
-bool AudioRendererAlgorithmBase::OutputFasterPlayback(uint8* dest) {
- DCHECK_LT(index_into_window_, window_size_);
- DCHECK_GT(playback_rate_, 1.0);
-
- if (audio_buffer_.forward_bytes() < bytes_per_frame_)
- return false;
-
- // The audio data is output in a series of windows. For sped-up playback,
- // the window is comprised of the following phases:
- //
- // a) Output raw data.
- // b) Save bytes for crossfade in |crossfade_buffer_|.
- // c) Drop data.
- // d) Output crossfaded audio leading up to the next window.
- //
- // The duration of each phase is computed below based on the |window_size_|
- // and |playback_rate_|.
- int input_step = window_size_;
- int output_step = ceil(window_size_ / playback_rate_);
- AlignToFrameBoundary(&output_step);
- DCHECK_GT(input_step, output_step);
-
- int bytes_to_crossfade = bytes_in_crossfade_;
- if (muted_ || bytes_to_crossfade > output_step)
- bytes_to_crossfade = 0;
-
- // This is the index of the end of phase a, beginning of phase b.
- int outtro_crossfade_begin = output_step - bytes_to_crossfade;
-
- // This is the index of the end of phase b, beginning of phase c.
- int outtro_crossfade_end = output_step;
-
- // This is the index of the end of phase c, beginning of phase d.
- // This phase continues until |index_into_window_| reaches |window_size_|, at
- // which point the window restarts.
- int intro_crossfade_begin = input_step - bytes_to_crossfade;
-
- // a) Output a raw frame if we haven't reached the crossfade section.
- if (index_into_window_ < outtro_crossfade_begin) {
- CopyWithAdvance(dest);
- index_into_window_ += bytes_per_frame_;
- return true;
- }
-
- // b) Save outtro crossfade frames into intermediate buffer, but do not output
- // anything to |dest|.
- while (index_into_window_ < outtro_crossfade_end) {
- if (audio_buffer_.forward_bytes() < bytes_per_frame_)
- return false;
-
- // This phase only applies if there are bytes to crossfade.
- DCHECK_GT(bytes_to_crossfade, 0);
- uint8* place_to_copy = crossfade_buffer_.get() +
- (index_into_window_ - outtro_crossfade_begin);
- CopyWithAdvance(place_to_copy);
- index_into_window_ += bytes_per_frame_;
- }
-
- // c) Drop frames until we reach the intro crossfade section.
- while (index_into_window_ < intro_crossfade_begin) {
- if (audio_buffer_.forward_bytes() < bytes_per_frame_)
- return false;
-
- DropFrame();
- index_into_window_ += bytes_per_frame_;
- }
-
- // Return if we have run out of data after Phase c).
- if (audio_buffer_.forward_bytes() < bytes_per_frame_)
- return false;
-
- // Phase d) doesn't apply if there are no bytes to crossfade.
- if (bytes_to_crossfade == 0) {
- DCHECK_EQ(index_into_window_, window_size_);
- return false;
- }
-
- // d) Crossfade and output a frame.
- DCHECK_LT(index_into_window_, window_size_);
- int offset_into_buffer = index_into_window_ - intro_crossfade_begin;
- memcpy(dest, crossfade_buffer_.get() + offset_into_buffer,
- bytes_per_frame_);
- scoped_array<uint8> intro_frame_ptr(new uint8[bytes_per_frame_]);
- audio_buffer_.Read(intro_frame_ptr.get(), bytes_per_frame_);
- OutputCrossfadedFrame(dest, intro_frame_ptr.get());
- index_into_window_ += bytes_per_frame_;
- return true;
-}
-
-bool AudioRendererAlgorithmBase::OutputSlowerPlayback(uint8* dest) {
- DCHECK_LT(index_into_window_, window_size_);
- DCHECK_LT(playback_rate_, 1.0);
- DCHECK_NE(playback_rate_, 0.0);
-
- if (audio_buffer_.forward_bytes() < bytes_per_frame_)
- return false;
-
- // The audio data is output in a series of windows. For slowed down playback,
- // the window is comprised of the following phases:
- //
- // a) Output raw data.
- // b) Output and save bytes for crossfade in |crossfade_buffer_|.
- // c) Output* raw data.
- // d) Output* crossfaded audio leading up to the next window.
- //
- // * Phases c) and d) do not progress |audio_buffer_|'s cursor so that the
- // |audio_buffer_|'s cursor is in the correct place for the next window.
- //
- // The duration of each phase is computed below based on the |window_size_|
- // and |playback_rate_|.
- int input_step = ceil(window_size_ * playback_rate_);
- AlignToFrameBoundary(&input_step);
- int output_step = window_size_;
- DCHECK_LT(input_step, output_step);
-
- int bytes_to_crossfade = bytes_in_crossfade_;
- if (muted_ || bytes_to_crossfade > input_step)
- bytes_to_crossfade = 0;
-
- // This is the index of the end of phase a, beginning of phase b.
- int intro_crossfade_begin = input_step - bytes_to_crossfade;
-
- // This is the index of the end of phase b, beginning of phase c.
- int intro_crossfade_end = input_step;
-
- // This is the index of the end of phase c, beginning of phase d.
- // This phase continues until |index_into_window_| reaches |window_size_|, at
- // which point the window restarts.
- int outtro_crossfade_begin = output_step - bytes_to_crossfade;
-
- // a) Output a raw frame.
- if (index_into_window_ < intro_crossfade_begin) {
- CopyWithAdvance(dest);
- index_into_window_ += bytes_per_frame_;
- return true;
- }
-
- // b) Save the raw frame for the intro crossfade section, then output the
- // frame to |dest|.
- if (index_into_window_ < intro_crossfade_end) {
- int offset = index_into_window_ - intro_crossfade_begin;
- uint8* place_to_copy = crossfade_buffer_.get() + offset;
- CopyWithoutAdvance(place_to_copy);
- CopyWithAdvance(dest);
- index_into_window_ += bytes_per_frame_;
- return true;
- }
-
- int audio_buffer_offset = index_into_window_ - intro_crossfade_end;
-
- if (audio_buffer_.forward_bytes() < audio_buffer_offset + bytes_per_frame_)
- return false;
-
- // c) Output a raw frame into |dest| without advancing the |audio_buffer_|
- // cursor. See function-level comment.
- DCHECK_GE(index_into_window_, intro_crossfade_end);
- CopyWithoutAdvance(dest, audio_buffer_offset);
-
- // d) Crossfade the next frame of |crossfade_buffer_| into |dest| if we've
- // reached the outtro crossfade section of the window.
- if (index_into_window_ >= outtro_crossfade_begin) {
- int offset_into_crossfade_buffer =
- index_into_window_ - outtro_crossfade_begin;
- uint8* intro_frame_ptr =
- crossfade_buffer_.get() + offset_into_crossfade_buffer;
- OutputCrossfadedFrame(dest, intro_frame_ptr);
- }
-
- index_into_window_ += bytes_per_frame_;
- return true;
-}
-
-bool AudioRendererAlgorithmBase::OutputNormalPlayback(uint8* dest) {
- if (audio_buffer_.forward_bytes() >= bytes_per_frame_) {
- CopyWithAdvance(dest);
- index_into_window_ += bytes_per_frame_;
- return true;
- }
- return false;
-}
-
-void AudioRendererAlgorithmBase::CopyWithAdvance(uint8* dest) {
- CopyWithoutAdvance(dest);
- DropFrame();
-}
-
-void AudioRendererAlgorithmBase::CopyWithoutAdvance(uint8* dest) {
- CopyWithoutAdvance(dest, 0);
-}
-
-void AudioRendererAlgorithmBase::CopyWithoutAdvance(
- uint8* dest, int offset) {
- if (muted_) {
- memset(dest, 0, bytes_per_frame_);
- return;
- }
- int copied = audio_buffer_.Peek(dest, bytes_per_frame_, offset);
- DCHECK_EQ(bytes_per_frame_, copied);
-}
-
-void AudioRendererAlgorithmBase::DropFrame() {
- audio_buffer_.Seek(bytes_per_frame_);
-
- if (!IsQueueFull())
- request_read_cb_.Run();
-}
-
-void AudioRendererAlgorithmBase::OutputCrossfadedFrame(
- uint8* outtro, const uint8* intro) {
- DCHECK_LE(index_into_window_, window_size_);
- DCHECK(!muted_);
-
- switch (bytes_per_channel_) {
- case 4:
- CrossfadeFrame<int32>(outtro, intro);
- break;
- case 2:
- CrossfadeFrame<int16>(outtro, intro);
- break;
- case 1:
- CrossfadeFrame<uint8>(outtro, intro);
- break;
- default:
- NOTREACHED() << "Unsupported audio bit depth in crossfade.";
- }
-}
-
-template <class Type>
-void AudioRendererAlgorithmBase::CrossfadeFrame(
- uint8* outtro_bytes, const uint8* intro_bytes) {
- Type* outtro = reinterpret_cast<Type*>(outtro_bytes);
- const Type* intro = reinterpret_cast<const Type*>(intro_bytes);
-
- int frames_in_crossfade = bytes_in_crossfade_ / bytes_per_frame_;
- float crossfade_ratio =
- static_cast<float>(crossfade_frame_number_) / frames_in_crossfade;
- for (int channel = 0; channel < channels_; ++channel) {
- *outtro *= 1.0 - crossfade_ratio;
- *outtro++ += (*intro++) * crossfade_ratio;
- }
- crossfade_frame_number_++;
-}
-
-void AudioRendererAlgorithmBase::SetPlaybackRate(float new_rate) {
- DCHECK_GE(new_rate, 0.0);
- playback_rate_ = new_rate;
- muted_ =
- playback_rate_ < kMinPlaybackRate || playback_rate_ > kMaxPlaybackRate;
-
- ResetWindow();
-}
-
-void AudioRendererAlgorithmBase::AlignToFrameBoundary(int* value) {
- (*value) -= ((*value) % bytes_per_frame_);
-}
-
-void AudioRendererAlgorithmBase::FlushBuffers() {
- ResetWindow();
-
- // Clear the queue of decoded packets (releasing the buffers).
- audio_buffer_.Clear();
- request_read_cb_.Run();
-}
-
-base::TimeDelta AudioRendererAlgorithmBase::GetTime() {
- return audio_buffer_.current_time();
-}
-
-void AudioRendererAlgorithmBase::EnqueueBuffer(Buffer* buffer_in) {
- DCHECK(!buffer_in->IsEndOfStream());
- audio_buffer_.Append(buffer_in);
- needs_more_data_ = false;
-
- // If we still don't have enough data, request more.
- if (!IsQueueFull())
- request_read_cb_.Run();
-}
-
-bool AudioRendererAlgorithmBase::NeedsMoreData() {
- return needs_more_data_ || IsQueueEmpty();
-}
-
-bool AudioRendererAlgorithmBase::IsQueueEmpty() {
- return audio_buffer_.forward_bytes() == 0;
-}
-
-bool AudioRendererAlgorithmBase::IsQueueFull() {
- return audio_buffer_.forward_bytes() >= audio_buffer_.forward_capacity();
-}
-
-int AudioRendererAlgorithmBase::QueueCapacity() {
- return audio_buffer_.forward_capacity();
-}
-
-void AudioRendererAlgorithmBase::IncreaseQueueCapacity() {
- audio_buffer_.set_forward_capacity(
- std::min(2 * audio_buffer_.forward_capacity(), kMaxBufferSizeInBytes));
-}
-
-} // namespace media
« no previous file with comments | « media/filters/audio_renderer_algorithm_base.h ('k') | media/filters/audio_renderer_algorithm_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698