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 |