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

Side by Side Diff: media/filters/audio_renderer_algorithm.cc

Issue 2536013002: Fix implicit channel layout configurations at non-1.0 playback rates. (Closed)
Patch Set: Created 4 years 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW
« 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