| OLD | NEW |
| 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 size_t kSamplesPer16kHzChannel = 160; | 22 const size_t kSamplesPer16kHzChannel = 160; |
| 23 const size_t kSamplesPer32kHzChannel = 320; | 23 const size_t kSamplesPer32kHzChannel = 320; |
| 24 const size_t kSamplesPer48kHzChannel = 480; | 24 const size_t kSamplesPer48kHzChannel = 480; |
| 25 | 25 |
| 26 int KeyboardChannelIndex(const StreamConfig& stream_config) { | 26 int KeyboardChannelIndex(const StreamConfig& stream_config) { |
| 27 if (!stream_config.has_keyboard()) { | 27 if (!stream_config.has_keyboard()) { |
| 28 assert(false); | 28 assert(false); |
| 29 return -1; | 29 return 0; |
| 30 } | 30 } |
| 31 | 31 |
| 32 return stream_config.num_channels(); | 32 return stream_config.num_channels(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 size_t NumBandsFromSamplesPerChannel(size_t num_frames) { | 35 size_t NumBandsFromSamplesPerChannel(size_t num_frames) { |
| 36 size_t num_bands = 1; | 36 size_t num_bands = 1; |
| 37 if (num_frames == kSamplesPer32kHzChannel || | 37 if (num_frames == kSamplesPer32kHzChannel || |
| 38 num_frames == kSamplesPer48kHzChannel) { | 38 num_frames == kSamplesPer48kHzChannel) { |
| 39 num_bands = rtc::CheckedDivExact(num_frames, kSamplesPer16kHzChannel); | 39 num_bands = rtc::CheckedDivExact(num_frames, kSamplesPer16kHzChannel); |
| 40 } | 40 } |
| 41 return num_bands; | 41 return num_bands; |
| 42 } | 42 } |
| 43 | 43 |
| 44 } // namespace | 44 } // namespace |
| 45 | 45 |
| 46 AudioBuffer::AudioBuffer(size_t input_num_frames, | 46 AudioBuffer::AudioBuffer(size_t input_num_frames, |
| 47 int num_input_channels, | 47 size_t num_input_channels, |
| 48 size_t process_num_frames, | 48 size_t process_num_frames, |
| 49 int num_process_channels, | 49 size_t num_process_channels, |
| 50 size_t output_num_frames) | 50 size_t output_num_frames) |
| 51 : input_num_frames_(input_num_frames), | 51 : input_num_frames_(input_num_frames), |
| 52 num_input_channels_(num_input_channels), | 52 num_input_channels_(num_input_channels), |
| 53 proc_num_frames_(process_num_frames), | 53 proc_num_frames_(process_num_frames), |
| 54 num_proc_channels_(num_process_channels), | 54 num_proc_channels_(num_process_channels), |
| 55 output_num_frames_(output_num_frames), | 55 output_num_frames_(output_num_frames), |
| 56 num_channels_(num_process_channels), | 56 num_channels_(num_process_channels), |
| 57 num_bands_(NumBandsFromSamplesPerChannel(proc_num_frames_)), | 57 num_bands_(NumBandsFromSamplesPerChannel(proc_num_frames_)), |
| 58 num_split_frames_(rtc::CheckedDivExact(proc_num_frames_, num_bands_)), | 58 num_split_frames_(rtc::CheckedDivExact(proc_num_frames_, num_bands_)), |
| 59 mixed_low_pass_valid_(false), | 59 mixed_low_pass_valid_(false), |
| 60 reference_copied_(false), | 60 reference_copied_(false), |
| 61 activity_(AudioFrame::kVadUnknown), | 61 activity_(AudioFrame::kVadUnknown), |
| 62 keyboard_data_(NULL), | 62 keyboard_data_(NULL), |
| 63 data_(new IFChannelBuffer(proc_num_frames_, num_proc_channels_)) { | 63 data_(new IFChannelBuffer(proc_num_frames_, num_proc_channels_)) { |
| 64 assert(input_num_frames_ > 0); | 64 assert(input_num_frames_ > 0); |
| 65 assert(proc_num_frames_ > 0); | 65 assert(proc_num_frames_ > 0); |
| 66 assert(output_num_frames_ > 0); | 66 assert(output_num_frames_ > 0); |
| 67 assert(num_input_channels_ > 0); | 67 assert(num_input_channels_ > 0); |
| 68 assert(num_proc_channels_ > 0 && num_proc_channels_ <= num_input_channels_); | 68 assert(num_proc_channels_ > 0 && num_proc_channels_ <= num_input_channels_); |
| 69 | 69 |
| 70 if (input_num_frames_ != proc_num_frames_ || | 70 if (input_num_frames_ != proc_num_frames_ || |
| 71 output_num_frames_ != proc_num_frames_) { | 71 output_num_frames_ != proc_num_frames_) { |
| 72 // Create an intermediate buffer for resampling. | 72 // Create an intermediate buffer for resampling. |
| 73 process_buffer_.reset(new ChannelBuffer<float>(proc_num_frames_, | 73 process_buffer_.reset(new ChannelBuffer<float>(proc_num_frames_, |
| 74 num_proc_channels_)); | 74 num_proc_channels_)); |
| 75 | 75 |
| 76 if (input_num_frames_ != proc_num_frames_) { | 76 if (input_num_frames_ != proc_num_frames_) { |
| 77 for (int i = 0; i < num_proc_channels_; ++i) { | 77 for (size_t i = 0; i < num_proc_channels_; ++i) { |
| 78 input_resamplers_.push_back( | 78 input_resamplers_.push_back( |
| 79 new PushSincResampler(input_num_frames_, | 79 new PushSincResampler(input_num_frames_, |
| 80 proc_num_frames_)); | 80 proc_num_frames_)); |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 if (output_num_frames_ != proc_num_frames_) { | 84 if (output_num_frames_ != proc_num_frames_) { |
| 85 for (int i = 0; i < num_proc_channels_; ++i) { | 85 for (size_t i = 0; i < num_proc_channels_; ++i) { |
| 86 output_resamplers_.push_back( | 86 output_resamplers_.push_back( |
| 87 new PushSincResampler(proc_num_frames_, | 87 new PushSincResampler(proc_num_frames_, |
| 88 output_num_frames_)); | 88 output_num_frames_)); |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 | 92 |
| 93 if (num_bands_ > 1) { | 93 if (num_bands_ > 1) { |
| 94 split_data_.reset(new IFChannelBuffer(proc_num_frames_, | 94 split_data_.reset(new IFChannelBuffer(proc_num_frames_, |
| 95 num_proc_channels_, | 95 num_proc_channels_, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 123 // Downmix. | 123 // Downmix. |
| 124 const float* const* data_ptr = data; | 124 const float* const* data_ptr = data; |
| 125 if (need_to_downmix) { | 125 if (need_to_downmix) { |
| 126 DownmixToMono<float, float>(data, input_num_frames_, num_input_channels_, | 126 DownmixToMono<float, float>(data, input_num_frames_, num_input_channels_, |
| 127 input_buffer_->fbuf()->channels()[0]); | 127 input_buffer_->fbuf()->channels()[0]); |
| 128 data_ptr = input_buffer_->fbuf_const()->channels(); | 128 data_ptr = input_buffer_->fbuf_const()->channels(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 // Resample. | 131 // Resample. |
| 132 if (input_num_frames_ != proc_num_frames_) { | 132 if (input_num_frames_ != proc_num_frames_) { |
| 133 for (int i = 0; i < num_proc_channels_; ++i) { | 133 for (size_t i = 0; i < num_proc_channels_; ++i) { |
| 134 input_resamplers_[i]->Resample(data_ptr[i], | 134 input_resamplers_[i]->Resample(data_ptr[i], |
| 135 input_num_frames_, | 135 input_num_frames_, |
| 136 process_buffer_->channels()[i], | 136 process_buffer_->channels()[i], |
| 137 proc_num_frames_); | 137 proc_num_frames_); |
| 138 } | 138 } |
| 139 data_ptr = process_buffer_->channels(); | 139 data_ptr = process_buffer_->channels(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 // Convert to the S16 range. | 142 // Convert to the S16 range. |
| 143 for (int i = 0; i < num_proc_channels_; ++i) { | 143 for (size_t i = 0; i < num_proc_channels_; ++i) { |
| 144 FloatToFloatS16(data_ptr[i], | 144 FloatToFloatS16(data_ptr[i], |
| 145 proc_num_frames_, | 145 proc_num_frames_, |
| 146 data_->fbuf()->channels()[i]); | 146 data_->fbuf()->channels()[i]); |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 | 149 |
| 150 void AudioBuffer::CopyTo(const StreamConfig& stream_config, | 150 void AudioBuffer::CopyTo(const StreamConfig& stream_config, |
| 151 float* const* data) { | 151 float* const* data) { |
| 152 assert(stream_config.num_frames() == output_num_frames_); | 152 assert(stream_config.num_frames() == output_num_frames_); |
| 153 assert(stream_config.num_channels() == num_channels_); | 153 assert(stream_config.num_channels() == num_channels_); |
| 154 | 154 |
| 155 // Convert to the float range. | 155 // Convert to the float range. |
| 156 float* const* data_ptr = data; | 156 float* const* data_ptr = data; |
| 157 if (output_num_frames_ != proc_num_frames_) { | 157 if (output_num_frames_ != proc_num_frames_) { |
| 158 // Convert to an intermediate buffer for subsequent resampling. | 158 // Convert to an intermediate buffer for subsequent resampling. |
| 159 data_ptr = process_buffer_->channels(); | 159 data_ptr = process_buffer_->channels(); |
| 160 } | 160 } |
| 161 for (int i = 0; i < num_channels_; ++i) { | 161 for (size_t i = 0; i < num_channels_; ++i) { |
| 162 FloatS16ToFloat(data_->fbuf()->channels()[i], | 162 FloatS16ToFloat(data_->fbuf()->channels()[i], |
| 163 proc_num_frames_, | 163 proc_num_frames_, |
| 164 data_ptr[i]); | 164 data_ptr[i]); |
| 165 } | 165 } |
| 166 | 166 |
| 167 // Resample. | 167 // Resample. |
| 168 if (output_num_frames_ != proc_num_frames_) { | 168 if (output_num_frames_ != proc_num_frames_) { |
| 169 for (int i = 0; i < num_channels_; ++i) { | 169 for (size_t i = 0; i < num_channels_; ++i) { |
| 170 output_resamplers_[i]->Resample(data_ptr[i], | 170 output_resamplers_[i]->Resample(data_ptr[i], |
| 171 proc_num_frames_, | 171 proc_num_frames_, |
| 172 data[i], | 172 data[i], |
| 173 output_num_frames_); | 173 output_num_frames_); |
| 174 } | 174 } |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 void AudioBuffer::InitForNewData() { | 178 void AudioBuffer::InitForNewData() { |
| 179 keyboard_data_ = NULL; | 179 keyboard_data_ = NULL; |
| 180 mixed_low_pass_valid_ = false; | 180 mixed_low_pass_valid_ = false; |
| 181 reference_copied_ = false; | 181 reference_copied_ = false; |
| 182 activity_ = AudioFrame::kVadUnknown; | 182 activity_ = AudioFrame::kVadUnknown; |
| 183 num_channels_ = num_proc_channels_; | 183 num_channels_ = num_proc_channels_; |
| 184 } | 184 } |
| 185 | 185 |
| 186 const int16_t* const* AudioBuffer::channels_const() const { | 186 const int16_t* const* AudioBuffer::channels_const() const { |
| 187 return data_->ibuf_const()->channels(); | 187 return data_->ibuf_const()->channels(); |
| 188 } | 188 } |
| 189 | 189 |
| 190 int16_t* const* AudioBuffer::channels() { | 190 int16_t* const* AudioBuffer::channels() { |
| 191 mixed_low_pass_valid_ = false; | 191 mixed_low_pass_valid_ = false; |
| 192 return data_->ibuf()->channels(); | 192 return data_->ibuf()->channels(); |
| 193 } | 193 } |
| 194 | 194 |
| 195 const int16_t* const* AudioBuffer::split_bands_const(int channel) const { | 195 const int16_t* const* AudioBuffer::split_bands_const(size_t channel) const { |
| 196 return split_data_.get() ? | 196 return split_data_.get() ? |
| 197 split_data_->ibuf_const()->bands(channel) : | 197 split_data_->ibuf_const()->bands(channel) : |
| 198 data_->ibuf_const()->bands(channel); | 198 data_->ibuf_const()->bands(channel); |
| 199 } | 199 } |
| 200 | 200 |
| 201 int16_t* const* AudioBuffer::split_bands(int channel) { | 201 int16_t* const* AudioBuffer::split_bands(size_t channel) { |
| 202 mixed_low_pass_valid_ = false; | 202 mixed_low_pass_valid_ = false; |
| 203 return split_data_.get() ? | 203 return split_data_.get() ? |
| 204 split_data_->ibuf()->bands(channel) : | 204 split_data_->ibuf()->bands(channel) : |
| 205 data_->ibuf()->bands(channel); | 205 data_->ibuf()->bands(channel); |
| 206 } | 206 } |
| 207 | 207 |
| 208 const int16_t* const* AudioBuffer::split_channels_const(Band band) const { | 208 const int16_t* const* AudioBuffer::split_channels_const(Band band) const { |
| 209 if (split_data_.get()) { | 209 if (split_data_.get()) { |
| 210 return split_data_->ibuf_const()->channels(band); | 210 return split_data_->ibuf_const()->channels(band); |
| 211 } else { | 211 } else { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 242 | 242 |
| 243 const float* const* AudioBuffer::channels_const_f() const { | 243 const float* const* AudioBuffer::channels_const_f() const { |
| 244 return data_->fbuf_const()->channels(); | 244 return data_->fbuf_const()->channels(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 float* const* AudioBuffer::channels_f() { | 247 float* const* AudioBuffer::channels_f() { |
| 248 mixed_low_pass_valid_ = false; | 248 mixed_low_pass_valid_ = false; |
| 249 return data_->fbuf()->channels(); | 249 return data_->fbuf()->channels(); |
| 250 } | 250 } |
| 251 | 251 |
| 252 const float* const* AudioBuffer::split_bands_const_f(int channel) const { | 252 const float* const* AudioBuffer::split_bands_const_f(size_t channel) const { |
| 253 return split_data_.get() ? | 253 return split_data_.get() ? |
| 254 split_data_->fbuf_const()->bands(channel) : | 254 split_data_->fbuf_const()->bands(channel) : |
| 255 data_->fbuf_const()->bands(channel); | 255 data_->fbuf_const()->bands(channel); |
| 256 } | 256 } |
| 257 | 257 |
| 258 float* const* AudioBuffer::split_bands_f(int channel) { | 258 float* const* AudioBuffer::split_bands_f(size_t channel) { |
| 259 mixed_low_pass_valid_ = false; | 259 mixed_low_pass_valid_ = false; |
| 260 return split_data_.get() ? | 260 return split_data_.get() ? |
| 261 split_data_->fbuf()->bands(channel) : | 261 split_data_->fbuf()->bands(channel) : |
| 262 data_->fbuf()->bands(channel); | 262 data_->fbuf()->bands(channel); |
| 263 } | 263 } |
| 264 | 264 |
| 265 const float* const* AudioBuffer::split_channels_const_f(Band band) const { | 265 const float* const* AudioBuffer::split_channels_const_f(Band band) const { |
| 266 if (split_data_.get()) { | 266 if (split_data_.get()) { |
| 267 return split_data_->fbuf_const()->channels(band); | 267 return split_data_->fbuf_const()->channels(band); |
| 268 } else { | 268 } else { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 } | 329 } |
| 330 | 330 |
| 331 void AudioBuffer::set_activity(AudioFrame::VADActivity activity) { | 331 void AudioBuffer::set_activity(AudioFrame::VADActivity activity) { |
| 332 activity_ = activity; | 332 activity_ = activity; |
| 333 } | 333 } |
| 334 | 334 |
| 335 AudioFrame::VADActivity AudioBuffer::activity() const { | 335 AudioFrame::VADActivity AudioBuffer::activity() const { |
| 336 return activity_; | 336 return activity_; |
| 337 } | 337 } |
| 338 | 338 |
| 339 int AudioBuffer::num_channels() const { | 339 size_t AudioBuffer::num_channels() const { |
| 340 return num_channels_; | 340 return num_channels_; |
| 341 } | 341 } |
| 342 | 342 |
| 343 void AudioBuffer::set_num_channels(int num_channels) { | 343 void AudioBuffer::set_num_channels(size_t num_channels) { |
| 344 num_channels_ = num_channels; | 344 num_channels_ = num_channels; |
| 345 } | 345 } |
| 346 | 346 |
| 347 size_t AudioBuffer::num_frames() const { | 347 size_t AudioBuffer::num_frames() const { |
| 348 return proc_num_frames_; | 348 return proc_num_frames_; |
| 349 } | 349 } |
| 350 | 350 |
| 351 size_t AudioBuffer::num_frames_per_band() const { | 351 size_t AudioBuffer::num_frames_per_band() const { |
| 352 return num_split_frames_; | 352 return num_split_frames_; |
| 353 } | 353 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 } else { | 386 } else { |
| 387 assert(num_proc_channels_ == num_input_channels_); | 387 assert(num_proc_channels_ == num_input_channels_); |
| 388 Deinterleave(frame->data_, | 388 Deinterleave(frame->data_, |
| 389 input_num_frames_, | 389 input_num_frames_, |
| 390 num_proc_channels_, | 390 num_proc_channels_, |
| 391 deinterleaved); | 391 deinterleaved); |
| 392 } | 392 } |
| 393 | 393 |
| 394 // Resample. | 394 // Resample. |
| 395 if (input_num_frames_ != proc_num_frames_) { | 395 if (input_num_frames_ != proc_num_frames_) { |
| 396 for (int i = 0; i < num_proc_channels_; ++i) { | 396 for (size_t i = 0; i < num_proc_channels_; ++i) { |
| 397 input_resamplers_[i]->Resample(input_buffer_->fbuf_const()->channels()[i], | 397 input_resamplers_[i]->Resample(input_buffer_->fbuf_const()->channels()[i], |
| 398 input_num_frames_, | 398 input_num_frames_, |
| 399 data_->fbuf()->channels()[i], | 399 data_->fbuf()->channels()[i], |
| 400 proc_num_frames_); | 400 proc_num_frames_); |
| 401 } | 401 } |
| 402 } | 402 } |
| 403 } | 403 } |
| 404 | 404 |
| 405 void AudioBuffer::InterleaveTo(AudioFrame* frame, bool data_changed) const { | 405 void AudioBuffer::InterleaveTo(AudioFrame* frame, bool data_changed) const { |
| 406 assert(proc_num_frames_ == output_num_frames_); | 406 assert(proc_num_frames_ == output_num_frames_); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 420 } | 420 } |
| 421 | 421 |
| 422 void AudioBuffer::CopyLowPassToReference() { | 422 void AudioBuffer::CopyLowPassToReference() { |
| 423 reference_copied_ = true; | 423 reference_copied_ = true; |
| 424 if (!low_pass_reference_channels_.get() || | 424 if (!low_pass_reference_channels_.get() || |
| 425 low_pass_reference_channels_->num_channels() != num_channels_) { | 425 low_pass_reference_channels_->num_channels() != num_channels_) { |
| 426 low_pass_reference_channels_.reset( | 426 low_pass_reference_channels_.reset( |
| 427 new ChannelBuffer<int16_t>(num_split_frames_, | 427 new ChannelBuffer<int16_t>(num_split_frames_, |
| 428 num_proc_channels_)); | 428 num_proc_channels_)); |
| 429 } | 429 } |
| 430 for (int i = 0; i < num_proc_channels_; i++) { | 430 for (size_t i = 0; i < num_proc_channels_; i++) { |
| 431 memcpy(low_pass_reference_channels_->channels()[i], | 431 memcpy(low_pass_reference_channels_->channels()[i], |
| 432 split_bands_const(i)[kBand0To8kHz], | 432 split_bands_const(i)[kBand0To8kHz], |
| 433 low_pass_reference_channels_->num_frames_per_band() * | 433 low_pass_reference_channels_->num_frames_per_band() * |
| 434 sizeof(split_bands_const(i)[kBand0To8kHz][0])); | 434 sizeof(split_bands_const(i)[kBand0To8kHz][0])); |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 | 437 |
| 438 void AudioBuffer::SplitIntoFrequencyBands() { | 438 void AudioBuffer::SplitIntoFrequencyBands() { |
| 439 splitting_filter_->Analysis(data_.get(), split_data_.get()); | 439 splitting_filter_->Analysis(data_.get(), split_data_.get()); |
| 440 } | 440 } |
| 441 | 441 |
| 442 void AudioBuffer::MergeFrequencyBands() { | 442 void AudioBuffer::MergeFrequencyBands() { |
| 443 splitting_filter_->Synthesis(split_data_.get(), data_.get()); | 443 splitting_filter_->Synthesis(split_data_.get(), data_.get()); |
| 444 } | 444 } |
| 445 | 445 |
| 446 } // namespace webrtc | 446 } // namespace webrtc |
| OLD | NEW |