| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/audio_renderer_algorithm.h" | 5 #include "media/filters/audio_renderer_algorithm.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 num_candidate_blocks_(0), | 75 num_candidate_blocks_(0), |
| 76 target_block_index_(0), | 76 target_block_index_(0), |
| 77 ola_window_size_(0), | 77 ola_window_size_(0), |
| 78 ola_hop_size_(0), | 78 ola_hop_size_(0), |
| 79 num_complete_frames_(0), | 79 num_complete_frames_(0), |
| 80 initial_capacity_(0), | 80 initial_capacity_(0), |
| 81 max_capacity_(0) {} | 81 max_capacity_(0) {} |
| 82 | 82 |
| 83 AudioRendererAlgorithm::~AudioRendererAlgorithm() {} | 83 AudioRendererAlgorithm::~AudioRendererAlgorithm() {} |
| 84 | 84 |
| 85 void AudioRendererAlgorithm::Initialize(const AudioParameters& params, | 85 void AudioRendererAlgorithm::Initialize(const AudioParameters& params) { |
| 86 std::vector<bool> channel_mask) { | |
| 87 CHECK(params.IsValid()); | 86 CHECK(params.IsValid()); |
| 88 | 87 |
| 89 channel_mask_ = std::move(channel_mask); | |
| 90 channels_ = params.channels(); | 88 channels_ = params.channels(); |
| 91 samples_per_second_ = params.sample_rate(); | 89 samples_per_second_ = params.sample_rate(); |
| 92 initial_capacity_ = capacity_ = | 90 initial_capacity_ = capacity_ = |
| 93 std::max(params.frames_per_buffer() * 2, | 91 std::max(params.frames_per_buffer() * 2, |
| 94 ConvertMillisecondsToFrames(kStartingCapacityInMs)); | 92 ConvertMillisecondsToFrames(kStartingCapacityInMs)); |
| 95 max_capacity_ = | 93 max_capacity_ = |
| 96 std::max(initial_capacity_, kMaxCapacityInSeconds * samples_per_second_); | 94 std::max(initial_capacity_, kMaxCapacityInSeconds * samples_per_second_); |
| 97 num_candidate_blocks_ = ConvertMillisecondsToFrames(kWsolaSearchIntervalMs); | 95 num_candidate_blocks_ = ConvertMillisecondsToFrames(kWsolaSearchIntervalMs); |
| 98 ola_window_size_ = ConvertMillisecondsToFrames(kOlaWindowSizeMs); | 96 ola_window_size_ = ConvertMillisecondsToFrames(kOlaWindowSizeMs); |
| 99 | 97 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 119 // center | 117 // center |
| 120 // X----X----------------X---------------X-----X | 118 // X----X----------------X---------------X-----X |
| 121 // <----------> <----------> | 119 // <----------> <----------> |
| 122 // Candidate ... Candidate | 120 // Candidate ... Candidate |
| 123 // 1, ... |num_candidate_blocks_| | 121 // 1, ... |num_candidate_blocks_| |
| 124 search_block_center_offset_ = | 122 search_block_center_offset_ = |
| 125 num_candidate_blocks_ / 2 + (ola_window_size_ / 2 - 1); | 123 num_candidate_blocks_ / 2 + (ola_window_size_ / 2 - 1); |
| 126 | 124 |
| 127 // If no mask is provided, assume all channels are valid. | 125 // If no mask is provided, assume all channels are valid. |
| 128 if (channel_mask_.empty()) | 126 if (channel_mask_.empty()) |
| 129 channel_mask_ = std::vector<bool>(channels_, true); | 127 SetChannelMask(std::vector<bool>(channels_, true)); |
| 130 DCHECK_EQ(channel_mask_.size(), static_cast<size_t>(channels_)); | 128 } |
| 129 |
| 130 void AudioRendererAlgorithm::SetChannelMask(std::vector<bool> channel_mask) { |
| 131 DCHECK_EQ(channel_mask.size(), static_cast<size_t>(channels_)); |
| 132 channel_mask_ = std::move(channel_mask); |
| 133 if (ola_window_) |
| 134 CreateSearchWrappers(); |
| 131 } | 135 } |
| 132 | 136 |
| 133 int AudioRendererAlgorithm::FillBuffer(AudioBus* dest, | 137 int AudioRendererAlgorithm::FillBuffer(AudioBus* dest, |
| 134 int dest_offset, | 138 int dest_offset, |
| 135 int requested_frames, | 139 int requested_frames, |
| 136 double playback_rate) { | 140 double playback_rate) { |
| 137 if (playback_rate == 0) | 141 if (playback_rate == 0) |
| 138 return 0; | 142 return 0; |
| 139 | 143 |
| 140 DCHECK_GT(playback_rate, 0); | 144 DCHECK_GT(playback_rate, 0); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 wsola_output_ = | 200 wsola_output_ = |
| 197 AudioBus::Create(channels_, ola_window_size_ + ola_hop_size_); | 201 AudioBus::Create(channels_, ola_window_size_ + ola_hop_size_); |
| 198 wsola_output_->Zero(); | 202 wsola_output_->Zero(); |
| 199 | 203 |
| 200 // Auxiliary containers. | 204 // Auxiliary containers. |
| 201 optimal_block_ = AudioBus::Create(channels_, ola_window_size_); | 205 optimal_block_ = AudioBus::Create(channels_, ola_window_size_); |
| 202 search_block_ = AudioBus::Create( | 206 search_block_ = AudioBus::Create( |
| 203 channels_, num_candidate_blocks_ + (ola_window_size_ - 1)); | 207 channels_, num_candidate_blocks_ + (ola_window_size_ - 1)); |
| 204 target_block_ = AudioBus::Create(channels_, ola_window_size_); | 208 target_block_ = AudioBus::Create(channels_, ola_window_size_); |
| 205 | 209 |
| 206 // WSOLA is quite expensive to run, so if a channel mask exists, use it to | 210 // Create potentially smaller wrappers for playback rate adaptation. |
| 207 // reduce the size of our search space. | 211 CreateSearchWrappers(); |
| 208 std::vector<float*> active_target_channels; | |
| 209 std::vector<float*> active_search_channels; | |
| 210 for (int ch = 0; ch < channels_; ++ch) { | |
| 211 if (channel_mask_[ch]) { | |
| 212 active_target_channels.push_back(target_block_->channel(ch)); | |
| 213 active_search_channels.push_back(search_block_->channel(ch)); | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 target_block_wrapper_ = | |
| 218 AudioBus::WrapVector(target_block_->frames(), active_target_channels); | |
| 219 search_block_wrapper_ = | |
| 220 AudioBus::WrapVector(search_block_->frames(), active_search_channels); | |
| 221 } | 212 } |
| 222 | 213 |
| 223 int rendered_frames = 0; | 214 int rendered_frames = 0; |
| 224 do { | 215 do { |
| 225 rendered_frames += | 216 rendered_frames += |
| 226 WriteCompletedFramesTo(requested_frames - rendered_frames, | 217 WriteCompletedFramesTo(requested_frames - rendered_frames, |
| 227 dest_offset + rendered_frames, dest); | 218 dest_offset + rendered_frames, dest); |
| 228 } while (rendered_frames < requested_frames && | 219 } while (rendered_frames < requested_frames && |
| 229 RunOneWsolaIteration(playback_rate)); | 220 RunOneWsolaIteration(playback_rate)); |
| 230 return rendered_frames; | 221 return rendered_frames; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 num_frames_to_read); | 416 num_frames_to_read); |
| 426 read_offset_frames = 0; | 417 read_offset_frames = 0; |
| 427 num_frames_to_read -= num_zero_frames_appended; | 418 num_frames_to_read -= num_zero_frames_appended; |
| 428 write_offset = num_zero_frames_appended; | 419 write_offset = num_zero_frames_appended; |
| 429 dest->ZeroFrames(num_zero_frames_appended); | 420 dest->ZeroFrames(num_zero_frames_appended); |
| 430 } | 421 } |
| 431 audio_buffer_.PeekFrames(num_frames_to_read, read_offset_frames, | 422 audio_buffer_.PeekFrames(num_frames_to_read, read_offset_frames, |
| 432 write_offset, dest); | 423 write_offset, dest); |
| 433 } | 424 } |
| 434 | 425 |
| 426 void AudioRendererAlgorithm::CreateSearchWrappers() { |
| 427 // WSOLA is quite expensive to run, so if a channel mask exists, use it to |
| 428 // reduce the size of our search space. |
| 429 std::vector<float*> active_target_channels; |
| 430 std::vector<float*> active_search_channels; |
| 431 for (int ch = 0; ch < channels_; ++ch) { |
| 432 if (channel_mask_[ch]) { |
| 433 active_target_channels.push_back(target_block_->channel(ch)); |
| 434 active_search_channels.push_back(search_block_->channel(ch)); |
| 435 } |
| 436 } |
| 437 |
| 438 target_block_wrapper_ = |
| 439 AudioBus::WrapVector(target_block_->frames(), active_target_channels); |
| 440 search_block_wrapper_ = |
| 441 AudioBus::WrapVector(search_block_->frames(), active_search_channels); |
| 442 } |
| 443 |
| 435 } // namespace media | 444 } // namespace media |
| OLD | NEW |