webrtc_m130/webrtc/common_audio/lapped_transform.cc
andrew@webrtc.org 04c50981f8 Add the Ooura FFT to RealFourier.
We are using the Ooura FFT in a few places:
- AGC
- Transient suppression
- Noise suppression

The optimized OpenMAX DL FFT is considerably faster, but currently does
not compile everywhere, notably on iOS. This change will allow us to use
Openmax when possible and otherwise fall back to Ooura.

(Unfortunately, noise suppression won't be able to take advantage of it
since it's not C++. Upgrade time?)

R=aluebs@webrtc.org, mgraczyk@chromium.org

Review URL: https://webrtc-codereview.appspot.com/45789004

Cr-Commit-Position: refs/heads/master@{#8798}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8798 4adac7df-926f-26a2-2b94-8c16560cd09d
2015-03-19 20:07:43 +00:00

90 lines
3.5 KiB
C++

/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/common_audio/lapped_transform.h"
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include "webrtc/base/checks.h"
#include "webrtc/common_audio/real_fourier.h"
namespace webrtc {
void LappedTransform::BlockThunk::ProcessBlock(const float* const* input,
int num_frames,
int num_input_channels,
int num_output_channels,
float* const* output) {
CHECK_EQ(num_input_channels, parent_->in_channels_);
CHECK_EQ(num_output_channels, parent_->out_channels_);
CHECK_EQ(parent_->block_length_, num_frames);
for (int i = 0; i < num_input_channels; ++i) {
memcpy(parent_->real_buf_.Row(i), input[i],
num_frames * sizeof(*input[0]));
parent_->fft_->Forward(parent_->real_buf_.Row(i),
parent_->cplx_pre_.Row(i));
}
int block_length = RealFourier::ComplexLength(
RealFourier::FftOrder(num_frames));
CHECK_EQ(parent_->cplx_length_, block_length);
parent_->block_processor_->ProcessAudioBlock(parent_->cplx_pre_.Array(),
num_input_channels,
parent_->cplx_length_,
num_output_channels,
parent_->cplx_post_.Array());
for (int i = 0; i < num_output_channels; ++i) {
parent_->fft_->Inverse(parent_->cplx_post_.Row(i),
parent_->real_buf_.Row(i));
memcpy(output[i], parent_->real_buf_.Row(i),
num_frames * sizeof(*input[0]));
}
}
LappedTransform::LappedTransform(int in_channels, int out_channels,
int chunk_length, const float* window,
int block_length, int shift_amount,
Callback* callback)
: blocker_callback_(this),
in_channels_(in_channels),
out_channels_(out_channels),
block_length_(block_length),
chunk_length_(chunk_length),
block_processor_(callback),
blocker_(
chunk_length_, block_length_, in_channels_, out_channels_, window,
shift_amount, &blocker_callback_),
fft_(RealFourier::Create(RealFourier::FftOrder(block_length_))),
cplx_length_(RealFourier::ComplexLength(fft_->order())),
real_buf_(in_channels, block_length_, RealFourier::kFftBufferAlignment),
cplx_pre_(in_channels, cplx_length_, RealFourier::kFftBufferAlignment),
cplx_post_(out_channels, cplx_length_, RealFourier::kFftBufferAlignment) {
CHECK(in_channels_ > 0 && out_channels_ > 0);
CHECK_GT(block_length_, 0);
CHECK_GT(chunk_length_, 0);
CHECK(block_processor_);
// block_length_ power of 2?
CHECK_EQ(0, block_length_ & (block_length_ - 1));
}
void LappedTransform::ProcessChunk(const float* const* in_chunk,
float* const* out_chunk) {
blocker_.ProcessChunk(in_chunk, chunk_length_, in_channels_, out_channels_,
out_chunk);
}
} // namespace webrtc