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

Unified Diff: media/filters/audio_renderer_algorithm.cc

Issue 2522673003: Don't run WSOLA over always muted channels. (Closed)
Patch Set: Fix cast tests. Created 4 years, 1 month 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
« no previous file with comments | « media/filters/audio_renderer_algorithm.h ('k') | media/filters/audio_renderer_algorithm_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/audio_renderer_algorithm.cc
diff --git a/media/filters/audio_renderer_algorithm.cc b/media/filters/audio_renderer_algorithm.cc
index ebe334a0f1a0c76c1063ed1c79512cc36fd4c6bb..275f939f55caac0c187f48f9aab7356f99ca8839 100644
--- a/media/filters/audio_renderer_algorithm.cc
+++ b/media/filters/audio_renderer_algorithm.cc
@@ -82,9 +82,11 @@ AudioRendererAlgorithm::AudioRendererAlgorithm()
AudioRendererAlgorithm::~AudioRendererAlgorithm() {}
-void AudioRendererAlgorithm::Initialize(const AudioParameters& params) {
+void AudioRendererAlgorithm::Initialize(const AudioParameters& params,
+ std::vector<bool> channel_mask) {
CHECK(params.IsValid());
+ channel_mask_ = std::move(channel_mask);
channels_ = params.channels();
samples_per_second_ = params.sample_rate();
initial_capacity_ = capacity_ =
@@ -137,6 +139,27 @@ void AudioRendererAlgorithm::Initialize(const AudioParameters& params) {
search_block_ = AudioBus::Create(
channels_, num_candidate_blocks_ + (ola_window_size_ - 1));
target_block_ = AudioBus::Create(channels_, ola_window_size_);
+
+ // If no mask is provided, assume all channels are valid.
+ if (channel_mask_.empty())
+ channel_mask_ = std::vector<bool>(channels_, true);
+ DCHECK_EQ(channel_mask_.size(), static_cast<size_t>(channels_));
+
+ // WSOLA is quite expensive to run, so if a channel mask exists, use it to
+ // reduce the size of our search space.
+ std::vector<float*> active_target_channels;
+ std::vector<float*> active_search_channels;
+ for (int ch = 0; ch < channels_; ++ch) {
+ if (channel_mask_[ch]) {
+ active_target_channels.push_back(target_block_->channel(ch));
+ active_search_channels.push_back(search_block_->channel(ch));
+ }
+ }
+
+ target_block_wrapper_ =
+ AudioBus::WrapVector(target_block_->frames(), active_target_channels);
+ search_block_wrapper_ =
+ AudioBus::WrapVector(search_block_->frames(), active_search_channels);
}
int AudioRendererAlgorithm::FillBuffer(AudioBus* dest,
@@ -254,11 +277,14 @@ bool AudioRendererAlgorithm::RunOneWsolaIteration(double playback_rate) {
// Overlap-and-add.
for (int k = 0; k < channels_; ++k) {
+ if (!channel_mask_[k])
+ continue;
+
const float* const ch_opt_frame = optimal_block_->channel(k);
float* ch_output = wsola_output_->channel(k) + num_complete_frames_;
for (int n = 0; n < ola_hop_size_; ++n) {
ch_output[n] = ch_output[n] * ola_window_[ola_hop_size_ + n] +
- ch_opt_frame[n] * ola_window_[n];
+ ch_opt_frame[n] * ola_window_[n];
}
// Copy the second half to the output.
@@ -310,6 +336,8 @@ int AudioRendererAlgorithm::WriteCompletedFramesTo(
// Remove the frames which are read.
int frames_to_move = wsola_output_->frames() - rendered_frames;
for (int k = 0; k < channels_; ++k) {
+ if (!channel_mask_[k])
+ continue;
float* ch = wsola_output_->channel(k);
memmove(ch, &ch[rendered_frames], sizeof(*ch) * frames_to_move);
}
@@ -338,16 +366,17 @@ void AudioRendererAlgorithm::GetOptimalBlock() {
} else {
PeekAudioWithZeroPrepend(target_block_index_, target_block_.get());
PeekAudioWithZeroPrepend(search_block_index_, search_block_.get());
- int last_optimal = target_block_index_ - ola_hop_size_ -
- search_block_index_;
- internal::Interval exclude_iterval = std::make_pair(
- last_optimal - kExcludeIntervalLengthFrames / 2,
- last_optimal + kExcludeIntervalLengthFrames / 2);
+ int last_optimal =
+ target_block_index_ - ola_hop_size_ - search_block_index_;
+ internal::Interval exclude_interval =
+ std::make_pair(last_optimal - kExcludeIntervalLengthFrames / 2,
+ last_optimal + kExcludeIntervalLengthFrames / 2);
// |optimal_index| is in frames and it is relative to the beginning of the
// |search_block_|.
- optimal_index = internal::OptimalIndex(
- search_block_.get(), target_block_.get(), exclude_iterval);
+ optimal_index =
+ internal::OptimalIndex(search_block_wrapper_.get(),
+ target_block_wrapper_.get(), exclude_interval);
// Translate |index| w.r.t. the beginning of |audio_buffer_| and extract the
// optimal block.
@@ -363,11 +392,13 @@ void AudioRendererAlgorithm::GetOptimalBlock() {
// where target-block has higher weight close to zero (weight of 1 at index
// 0) and lower weight close the end.
for (int k = 0; k < channels_; ++k) {
+ if (!channel_mask_[k])
+ continue;
float* ch_opt = optimal_block_->channel(k);
const float* const ch_target = target_block_->channel(k);
for (int n = 0; n < ola_window_size_; ++n) {
- ch_opt[n] = ch_opt[n] * transition_window_[n] + ch_target[n] *
- transition_window_[ola_window_size_ + n];
+ ch_opt[n] = ch_opt[n] * transition_window_[n] +
+ ch_target[n] * transition_window_[ola_window_size_ + n];
}
}
}
« no previous file with comments | « media/filters/audio_renderer_algorithm.h ('k') | media/filters/audio_renderer_algorithm_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698