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

Side by Side Diff: webrtc/modules/audio_processing/audio_buffer.cc

Issue 1253573005: Revert of Allow more than 2 input channels in AudioProcessing. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 5 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_processing/audio_buffer.h" 11 #include "webrtc/modules/audio_processing/audio_buffer.h"
12 12
13 #include "webrtc/common_audio/include/audio_util.h" 13 #include "webrtc/common_audio/include/audio_util.h"
14 #include "webrtc/common_audio/resampler/push_sinc_resampler.h" 14 #include "webrtc/common_audio/resampler/push_sinc_resampler.h"
15 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 15 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
16 #include "webrtc/common_audio/channel_buffer.h" 16 #include "webrtc/common_audio/channel_buffer.h"
17 #include "webrtc/modules/audio_processing/common.h" 17 #include "webrtc/modules/audio_processing/common.h"
18 18
19 namespace webrtc { 19 namespace webrtc {
20 namespace { 20 namespace {
21 21
22 const int kSamplesPer16kHzChannel = 160; 22 const int kSamplesPer16kHzChannel = 160;
23 const int kSamplesPer32kHzChannel = 320; 23 const int kSamplesPer32kHzChannel = 320;
24 const int kSamplesPer48kHzChannel = 480; 24 const int kSamplesPer48kHzChannel = 480;
25 25
26 int KeyboardChannelIndex(const StreamConfig& stream_config) { 26 bool HasKeyboardChannel(AudioProcessing::ChannelLayout layout) {
27 if (!stream_config.has_keyboard()) { 27 switch (layout) {
28 assert(false); 28 case AudioProcessing::kMono:
29 return -1; 29 case AudioProcessing::kStereo:
30 return false;
31 case AudioProcessing::kMonoAndKeyboard:
32 case AudioProcessing::kStereoAndKeyboard:
33 return true;
30 } 34 }
35 assert(false);
36 return false;
37 }
31 38
32 return stream_config.num_channels(); 39 int KeyboardChannelIndex(AudioProcessing::ChannelLayout layout) {
40 switch (layout) {
41 case AudioProcessing::kMono:
42 case AudioProcessing::kStereo:
43 assert(false);
44 return -1;
45 case AudioProcessing::kMonoAndKeyboard:
46 return 1;
47 case AudioProcessing::kStereoAndKeyboard:
48 return 2;
49 }
50 assert(false);
51 return -1;
52 }
53
54 template <typename T>
55 void StereoToMono(const T* left, const T* right, T* out,
56 int num_frames) {
57 for (int i = 0; i < num_frames; ++i)
58 out[i] = (left[i] + right[i]) / 2;
33 } 59 }
34 60
35 int NumBandsFromSamplesPerChannel(int num_frames) { 61 int NumBandsFromSamplesPerChannel(int num_frames) {
36 int num_bands = 1; 62 int num_bands = 1;
37 if (num_frames == kSamplesPer32kHzChannel || 63 if (num_frames == kSamplesPer32kHzChannel ||
38 num_frames == kSamplesPer48kHzChannel) { 64 num_frames == kSamplesPer48kHzChannel) {
39 num_bands = rtc::CheckedDivExact(num_frames, 65 num_bands = rtc::CheckedDivExact(num_frames,
40 static_cast<int>(kSamplesPer16kHzChannel)); 66 static_cast<int>(kSamplesPer16kHzChannel));
41 } 67 }
42 return num_bands; 68 return num_bands;
(...skipping 15 matching lines...) Expand all
58 num_bands_(NumBandsFromSamplesPerChannel(proc_num_frames_)), 84 num_bands_(NumBandsFromSamplesPerChannel(proc_num_frames_)),
59 num_split_frames_(rtc::CheckedDivExact(proc_num_frames_, num_bands_)), 85 num_split_frames_(rtc::CheckedDivExact(proc_num_frames_, num_bands_)),
60 mixed_low_pass_valid_(false), 86 mixed_low_pass_valid_(false),
61 reference_copied_(false), 87 reference_copied_(false),
62 activity_(AudioFrame::kVadUnknown), 88 activity_(AudioFrame::kVadUnknown),
63 keyboard_data_(NULL), 89 keyboard_data_(NULL),
64 data_(new IFChannelBuffer(proc_num_frames_, num_proc_channels_)) { 90 data_(new IFChannelBuffer(proc_num_frames_, num_proc_channels_)) {
65 assert(input_num_frames_ > 0); 91 assert(input_num_frames_ > 0);
66 assert(proc_num_frames_ > 0); 92 assert(proc_num_frames_ > 0);
67 assert(output_num_frames_ > 0); 93 assert(output_num_frames_ > 0);
68 assert(num_input_channels_ > 0); 94 assert(num_input_channels_ > 0 && num_input_channels_ <= 2);
69 assert(num_proc_channels_ > 0 && num_proc_channels_ <= num_input_channels_); 95 assert(num_proc_channels_ > 0 && num_proc_channels_ <= num_input_channels_);
70 96
71 if (input_num_frames_ != proc_num_frames_ || 97 if (input_num_frames_ != proc_num_frames_ ||
72 output_num_frames_ != proc_num_frames_) { 98 output_num_frames_ != proc_num_frames_) {
73 // Create an intermediate buffer for resampling. 99 // Create an intermediate buffer for resampling.
74 process_buffer_.reset(new ChannelBuffer<float>(proc_num_frames_, 100 process_buffer_.reset(new ChannelBuffer<float>(proc_num_frames_,
75 num_proc_channels_)); 101 num_proc_channels_));
76 102
77 if (input_num_frames_ != proc_num_frames_) { 103 if (input_num_frames_ != proc_num_frames_) {
78 for (int i = 0; i < num_proc_channels_; ++i) { 104 for (int i = 0; i < num_proc_channels_; ++i) {
(...skipping 18 matching lines...) Expand all
97 num_bands_)); 123 num_bands_));
98 splitting_filter_.reset(new SplittingFilter(num_proc_channels_, 124 splitting_filter_.reset(new SplittingFilter(num_proc_channels_,
99 num_bands_, 125 num_bands_,
100 proc_num_frames_)); 126 proc_num_frames_));
101 } 127 }
102 } 128 }
103 129
104 AudioBuffer::~AudioBuffer() {} 130 AudioBuffer::~AudioBuffer() {}
105 131
106 void AudioBuffer::CopyFrom(const float* const* data, 132 void AudioBuffer::CopyFrom(const float* const* data,
107 const StreamConfig& stream_config) { 133 int num_frames,
108 assert(stream_config.num_frames() == input_num_frames_); 134 AudioProcessing::ChannelLayout layout) {
109 assert(stream_config.num_channels() == num_input_channels_); 135 assert(num_frames == input_num_frames_);
136 assert(ChannelsFromLayout(layout) == num_input_channels_);
110 InitForNewData(); 137 InitForNewData();
111 // Initialized lazily because there's a different condition in 138 // Initialized lazily because there's a different condition in
112 // DeinterleaveFrom. 139 // DeinterleaveFrom.
113 const bool need_to_downmix = 140 if ((num_input_channels_ == 2 && num_proc_channels_ == 1) && !input_buffer_) {
114 num_input_channels_ > 1 && num_proc_channels_ == 1;
115 if (need_to_downmix && !input_buffer_) {
116 input_buffer_.reset( 141 input_buffer_.reset(
117 new IFChannelBuffer(input_num_frames_, num_proc_channels_)); 142 new IFChannelBuffer(input_num_frames_, num_proc_channels_));
118 } 143 }
119 144
120 if (stream_config.has_keyboard()) { 145 if (HasKeyboardChannel(layout)) {
121 keyboard_data_ = data[KeyboardChannelIndex(stream_config)]; 146 keyboard_data_ = data[KeyboardChannelIndex(layout)];
122 } 147 }
123 148
124 // Downmix. 149 // Downmix.
125 const float* const* data_ptr = data; 150 const float* const* data_ptr = data;
126 if (need_to_downmix) { 151 if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
127 DownmixToMono<float, float>(data, input_num_frames_, num_input_channels_, 152 StereoToMono(data[0],
128 input_buffer_->fbuf()->channels()[0]); 153 data[1],
154 input_buffer_->fbuf()->channels()[0],
155 input_num_frames_);
129 data_ptr = input_buffer_->fbuf_const()->channels(); 156 data_ptr = input_buffer_->fbuf_const()->channels();
130 } 157 }
131 158
132 // Resample. 159 // Resample.
133 if (input_num_frames_ != proc_num_frames_) { 160 if (input_num_frames_ != proc_num_frames_) {
134 for (int i = 0; i < num_proc_channels_; ++i) { 161 for (int i = 0; i < num_proc_channels_; ++i) {
135 input_resamplers_[i]->Resample(data_ptr[i], 162 input_resamplers_[i]->Resample(data_ptr[i],
136 input_num_frames_, 163 input_num_frames_,
137 process_buffer_->channels()[i], 164 process_buffer_->channels()[i],
138 proc_num_frames_); 165 proc_num_frames_);
139 } 166 }
140 data_ptr = process_buffer_->channels(); 167 data_ptr = process_buffer_->channels();
141 } 168 }
142 169
143 // Convert to the S16 range. 170 // Convert to the S16 range.
144 for (int i = 0; i < num_proc_channels_; ++i) { 171 for (int i = 0; i < num_proc_channels_; ++i) {
145 FloatToFloatS16(data_ptr[i], 172 FloatToFloatS16(data_ptr[i],
146 proc_num_frames_, 173 proc_num_frames_,
147 data_->fbuf()->channels()[i]); 174 data_->fbuf()->channels()[i]);
148 } 175 }
149 } 176 }
150 177
151 void AudioBuffer::CopyTo(const StreamConfig& stream_config, 178 void AudioBuffer::CopyTo(int num_frames,
179 AudioProcessing::ChannelLayout layout,
152 float* const* data) { 180 float* const* data) {
153 assert(stream_config.num_frames() == output_num_frames_); 181 assert(num_frames == output_num_frames_);
154 assert(stream_config.num_channels() == num_channels_); 182 assert(ChannelsFromLayout(layout) == num_channels_);
155 183
156 // Convert to the float range. 184 // Convert to the float range.
157 float* const* data_ptr = data; 185 float* const* data_ptr = data;
158 if (output_num_frames_ != proc_num_frames_) { 186 if (output_num_frames_ != proc_num_frames_) {
159 // Convert to an intermediate buffer for subsequent resampling. 187 // Convert to an intermediate buffer for subsequent resampling.
160 data_ptr = process_buffer_->channels(); 188 data_ptr = process_buffer_->channels();
161 } 189 }
162 for (int i = 0; i < num_channels_; ++i) { 190 for (int i = 0; i < num_channels_; ++i) {
163 FloatS16ToFloat(data_->fbuf()->channels()[i], 191 FloatS16ToFloat(data_->fbuf()->channels()[i],
164 proc_num_frames_, 192 proc_num_frames_,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 ChannelBuffer<float>* AudioBuffer::split_data_f() { 320 ChannelBuffer<float>* AudioBuffer::split_data_f() {
293 mixed_low_pass_valid_ = false; 321 mixed_low_pass_valid_ = false;
294 return split_data_.get() ? split_data_->fbuf() : data_->fbuf(); 322 return split_data_.get() ? split_data_->fbuf() : data_->fbuf();
295 } 323 }
296 324
297 const ChannelBuffer<float>* AudioBuffer::split_data_f() const { 325 const ChannelBuffer<float>* AudioBuffer::split_data_f() const {
298 return split_data_.get() ? split_data_->fbuf_const() : data_->fbuf_const(); 326 return split_data_.get() ? split_data_->fbuf_const() : data_->fbuf_const();
299 } 327 }
300 328
301 const int16_t* AudioBuffer::mixed_low_pass_data() { 329 const int16_t* AudioBuffer::mixed_low_pass_data() {
330 // Currently only mixing stereo to mono is supported.
331 assert(num_proc_channels_ == 1 || num_proc_channels_ == 2);
332
302 if (num_proc_channels_ == 1) { 333 if (num_proc_channels_ == 1) {
303 return split_bands_const(0)[kBand0To8kHz]; 334 return split_bands_const(0)[kBand0To8kHz];
304 } 335 }
305 336
306 if (!mixed_low_pass_valid_) { 337 if (!mixed_low_pass_valid_) {
307 if (!mixed_low_pass_channels_.get()) { 338 if (!mixed_low_pass_channels_.get()) {
308 mixed_low_pass_channels_.reset( 339 mixed_low_pass_channels_.reset(
309 new ChannelBuffer<int16_t>(num_split_frames_, 1)); 340 new ChannelBuffer<int16_t>(num_split_frames_, 1));
310 } 341 }
311 342 StereoToMono(split_bands_const(0)[kBand0To8kHz],
312 DownmixToMono<int16_t, int32_t>(split_channels_const(kBand0To8kHz), 343 split_bands_const(1)[kBand0To8kHz],
313 num_split_frames_, num_channels_, 344 mixed_low_pass_channels_->channels()[0],
314 mixed_low_pass_channels_->channels()[0]); 345 num_split_frames_);
315 mixed_low_pass_valid_ = true; 346 mixed_low_pass_valid_ = true;
316 } 347 }
317 return mixed_low_pass_channels_->channels()[0]; 348 return mixed_low_pass_channels_->channels()[0];
318 } 349 }
319 350
320 const int16_t* AudioBuffer::low_pass_reference(int channel) const { 351 const int16_t* AudioBuffer::low_pass_reference(int channel) const {
321 if (!reference_copied_) { 352 if (!reference_copied_) {
322 return NULL; 353 return NULL;
323 } 354 }
324 355
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 new IFChannelBuffer(input_num_frames_, num_proc_channels_)); 404 new IFChannelBuffer(input_num_frames_, num_proc_channels_));
374 } 405 }
375 activity_ = frame->vad_activity_; 406 activity_ = frame->vad_activity_;
376 407
377 int16_t* const* deinterleaved; 408 int16_t* const* deinterleaved;
378 if (input_num_frames_ == proc_num_frames_) { 409 if (input_num_frames_ == proc_num_frames_) {
379 deinterleaved = data_->ibuf()->channels(); 410 deinterleaved = data_->ibuf()->channels();
380 } else { 411 } else {
381 deinterleaved = input_buffer_->ibuf()->channels(); 412 deinterleaved = input_buffer_->ibuf()->channels();
382 } 413 }
383 if (num_proc_channels_ == 1) { 414 if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
384 // Downmix and deinterleave simultaneously. 415 // Downmix directly; no explicit deinterleaving needed.
385 DownmixInterleavedToMono(frame->data_, input_num_frames_, 416 for (int i = 0; i < input_num_frames_; ++i) {
386 num_input_channels_, deinterleaved[0]); 417 deinterleaved[0][i] = (frame->data_[i * 2] + frame->data_[i * 2 + 1]) / 2;
418 }
387 } else { 419 } else {
388 assert(num_proc_channels_ == num_input_channels_); 420 assert(num_proc_channels_ == num_input_channels_);
389 Deinterleave(frame->data_, 421 Deinterleave(frame->data_,
390 input_num_frames_, 422 input_num_frames_,
391 num_proc_channels_, 423 num_proc_channels_,
392 deinterleaved); 424 deinterleaved);
393 } 425 }
394 426
395 // Resample. 427 // Resample.
396 if (input_num_frames_ != proc_num_frames_) { 428 if (input_num_frames_ != proc_num_frames_) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 470
439 void AudioBuffer::SplitIntoFrequencyBands() { 471 void AudioBuffer::SplitIntoFrequencyBands() {
440 splitting_filter_->Analysis(data_.get(), split_data_.get()); 472 splitting_filter_->Analysis(data_.get(), split_data_.get());
441 } 473 }
442 474
443 void AudioBuffer::MergeFrequencyBands() { 475 void AudioBuffer::MergeFrequencyBands() {
444 splitting_filter_->Synthesis(split_data_.get(), data_.get()); 476 splitting_filter_->Synthesis(split_data_.get(), data_.get());
445 } 477 }
446 478
447 } // namespace webrtc 479 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/audio_buffer.h ('k') | webrtc/modules/audio_processing/audio_processing_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698