| Index: webrtc/modules/audio_processing/audio_buffer.cc
|
| diff --git a/webrtc/modules/audio_processing/audio_buffer.cc b/webrtc/modules/audio_processing/audio_buffer.cc
|
| index 9073ad7569732a8e9c204b93689c30be86275709..04dcaea799d60af6bbc48d899e9ded8134d6ce03 100644
|
| --- a/webrtc/modules/audio_processing/audio_buffer.cc
|
| +++ b/webrtc/modules/audio_processing/audio_buffer.cc
|
| @@ -23,13 +23,39 @@
|
| const int kSamplesPer32kHzChannel = 320;
|
| const int kSamplesPer48kHzChannel = 480;
|
|
|
| -int KeyboardChannelIndex(const StreamConfig& stream_config) {
|
| - if (!stream_config.has_keyboard()) {
|
| - assert(false);
|
| - return -1;
|
| - }
|
| -
|
| - return stream_config.num_channels();
|
| +bool HasKeyboardChannel(AudioProcessing::ChannelLayout layout) {
|
| + switch (layout) {
|
| + case AudioProcessing::kMono:
|
| + case AudioProcessing::kStereo:
|
| + return false;
|
| + case AudioProcessing::kMonoAndKeyboard:
|
| + case AudioProcessing::kStereoAndKeyboard:
|
| + return true;
|
| + }
|
| + assert(false);
|
| + return false;
|
| +}
|
| +
|
| +int KeyboardChannelIndex(AudioProcessing::ChannelLayout layout) {
|
| + switch (layout) {
|
| + case AudioProcessing::kMono:
|
| + case AudioProcessing::kStereo:
|
| + assert(false);
|
| + return -1;
|
| + case AudioProcessing::kMonoAndKeyboard:
|
| + return 1;
|
| + case AudioProcessing::kStereoAndKeyboard:
|
| + return 2;
|
| + }
|
| + assert(false);
|
| + return -1;
|
| +}
|
| +
|
| +template <typename T>
|
| +void StereoToMono(const T* left, const T* right, T* out,
|
| + int num_frames) {
|
| + for (int i = 0; i < num_frames; ++i)
|
| + out[i] = (left[i] + right[i]) / 2;
|
| }
|
|
|
| int NumBandsFromSamplesPerChannel(int num_frames) {
|
| @@ -65,7 +91,7 @@
|
| assert(input_num_frames_ > 0);
|
| assert(proc_num_frames_ > 0);
|
| assert(output_num_frames_ > 0);
|
| - assert(num_input_channels_ > 0);
|
| + assert(num_input_channels_ > 0 && num_input_channels_ <= 2);
|
| assert(num_proc_channels_ > 0 && num_proc_channels_ <= num_input_channels_);
|
|
|
| if (input_num_frames_ != proc_num_frames_ ||
|
| @@ -104,28 +130,29 @@
|
| AudioBuffer::~AudioBuffer() {}
|
|
|
| void AudioBuffer::CopyFrom(const float* const* data,
|
| - const StreamConfig& stream_config) {
|
| - assert(stream_config.num_frames() == input_num_frames_);
|
| - assert(stream_config.num_channels() == num_input_channels_);
|
| + int num_frames,
|
| + AudioProcessing::ChannelLayout layout) {
|
| + assert(num_frames == input_num_frames_);
|
| + assert(ChannelsFromLayout(layout) == num_input_channels_);
|
| InitForNewData();
|
| // Initialized lazily because there's a different condition in
|
| // DeinterleaveFrom.
|
| - const bool need_to_downmix =
|
| - num_input_channels_ > 1 && num_proc_channels_ == 1;
|
| - if (need_to_downmix && !input_buffer_) {
|
| + if ((num_input_channels_ == 2 && num_proc_channels_ == 1) && !input_buffer_) {
|
| input_buffer_.reset(
|
| new IFChannelBuffer(input_num_frames_, num_proc_channels_));
|
| }
|
|
|
| - if (stream_config.has_keyboard()) {
|
| - keyboard_data_ = data[KeyboardChannelIndex(stream_config)];
|
| + if (HasKeyboardChannel(layout)) {
|
| + keyboard_data_ = data[KeyboardChannelIndex(layout)];
|
| }
|
|
|
| // Downmix.
|
| const float* const* data_ptr = data;
|
| - if (need_to_downmix) {
|
| - DownmixToMono<float, float>(data, input_num_frames_, num_input_channels_,
|
| - input_buffer_->fbuf()->channels()[0]);
|
| + if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
|
| + StereoToMono(data[0],
|
| + data[1],
|
| + input_buffer_->fbuf()->channels()[0],
|
| + input_num_frames_);
|
| data_ptr = input_buffer_->fbuf_const()->channels();
|
| }
|
|
|
| @@ -148,10 +175,11 @@
|
| }
|
| }
|
|
|
| -void AudioBuffer::CopyTo(const StreamConfig& stream_config,
|
| +void AudioBuffer::CopyTo(int num_frames,
|
| + AudioProcessing::ChannelLayout layout,
|
| float* const* data) {
|
| - assert(stream_config.num_frames() == output_num_frames_);
|
| - assert(stream_config.num_channels() == num_channels_);
|
| + assert(num_frames == output_num_frames_);
|
| + assert(ChannelsFromLayout(layout) == num_channels_);
|
|
|
| // Convert to the float range.
|
| float* const* data_ptr = data;
|
| @@ -299,6 +327,9 @@
|
| }
|
|
|
| const int16_t* AudioBuffer::mixed_low_pass_data() {
|
| + // Currently only mixing stereo to mono is supported.
|
| + assert(num_proc_channels_ == 1 || num_proc_channels_ == 2);
|
| +
|
| if (num_proc_channels_ == 1) {
|
| return split_bands_const(0)[kBand0To8kHz];
|
| }
|
| @@ -308,10 +339,10 @@
|
| mixed_low_pass_channels_.reset(
|
| new ChannelBuffer<int16_t>(num_split_frames_, 1));
|
| }
|
| -
|
| - DownmixToMono<int16_t, int32_t>(split_channels_const(kBand0To8kHz),
|
| - num_split_frames_, num_channels_,
|
| - mixed_low_pass_channels_->channels()[0]);
|
| + StereoToMono(split_bands_const(0)[kBand0To8kHz],
|
| + split_bands_const(1)[kBand0To8kHz],
|
| + mixed_low_pass_channels_->channels()[0],
|
| + num_split_frames_);
|
| mixed_low_pass_valid_ = true;
|
| }
|
| return mixed_low_pass_channels_->channels()[0];
|
| @@ -380,10 +411,11 @@
|
| } else {
|
| deinterleaved = input_buffer_->ibuf()->channels();
|
| }
|
| - if (num_proc_channels_ == 1) {
|
| - // Downmix and deinterleave simultaneously.
|
| - DownmixInterleavedToMono(frame->data_, input_num_frames_,
|
| - num_input_channels_, deinterleaved[0]);
|
| + if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
|
| + // Downmix directly; no explicit deinterleaving needed.
|
| + for (int i = 0; i < input_num_frames_; ++i) {
|
| + deinterleaved[0][i] = (frame->data_[i * 2] + frame->data_[i * 2 + 1]) / 2;
|
| + }
|
| } else {
|
| assert(num_proc_channels_ == num_input_channels_);
|
| Deinterleave(frame->data_,
|
|
|