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
diff --git a/webrtc/common_audio/real_fourier.cc b/webrtc/common_audio/real_fourier.cc
index 81fd45c..dec2be6 100644
--- a/webrtc/common_audio/real_fourier.cc
+++ b/webrtc/common_audio/real_fourier.cc
@@ -10,54 +10,37 @@
#include "webrtc/common_audio/real_fourier.h"
-#include <cstdlib>
-
-#include "dl/sp/api/omxSP.h"
#include "webrtc/base/checks.h"
+#include "webrtc/common_audio/real_fourier_ooura.h"
+#include "webrtc/common_audio/real_fourier_openmax.h"
+#include "webrtc/common_audio/signal_processing/include/spl_inl.h"
namespace webrtc {
using std::complex;
-// The omx implementation uses this macro to check order validity.
-const int RealFourier::kMaxFftOrder = TWIDDLE_TABLE_ORDER;
const int RealFourier::kFftBufferAlignment = 32;
-RealFourier::RealFourier(int fft_order)
- : order_(fft_order),
- omx_spec_(nullptr) {
- CHECK_GE(order_, 1);
- CHECK_LE(order_, kMaxFftOrder);
-
- OMX_INT buffer_size;
- OMXResult r;
-
- r = omxSP_FFTGetBufSize_R_F32(order_, &buffer_size);
- CHECK_EQ(r, OMX_Sts_NoErr);
-
- omx_spec_ = malloc(buffer_size);
- DCHECK(omx_spec_);
-
- r = omxSP_FFTInit_R_F32(omx_spec_, order_);
- CHECK_EQ(r, OMX_Sts_NoErr);
-}
-
-RealFourier::~RealFourier() {
- free(omx_spec_);
+rtc::scoped_ptr<RealFourier> RealFourier::Create(int fft_order) {
+#if defined(RTC_USE_OPENMAX_DL)
+ return rtc::scoped_ptr<RealFourier>(new RealFourierOpenmax(fft_order));
+#else
+ return rtc::scoped_ptr<RealFourier>(new RealFourierOoura(fft_order));
+#endif
}
int RealFourier::FftOrder(int length) {
- for (int order = 0; order <= kMaxFftOrder; order++) {
- if ((1 << order) >= length) {
- return order;
- }
- }
- return -1;
+ CHECK_GT(length, 0);
+ return WebRtcSpl_GetSizeInBits(length - 1);
+}
+
+int RealFourier::FftLength(int order) {
+ CHECK_GE(order, 0);
+ return 1 << order;
}
int RealFourier::ComplexLength(int order) {
- CHECK_LE(order, kMaxFftOrder);
- CHECK_GT(order, 0);
+ CHECK_GE(order, 0);
return (1 << order) / 2 + 1;
}
@@ -71,18 +54,5 @@
AlignedMalloc(sizeof(complex<float>) * count, kFftBufferAlignment)));
}
-void RealFourier::Forward(const float* src, complex<float>* dest) const {
- OMXResult r;
- r = omxSP_FFTFwd_RToCCS_F32(src, reinterpret_cast<OMX_F32*>(dest), omx_spec_);
- CHECK_EQ(r, OMX_Sts_NoErr);
-}
-
-void RealFourier::Inverse(const complex<float>* src, float* dest) const {
- OMXResult r;
- r = omxSP_FFTInv_CCSToR_F32(reinterpret_cast<const OMX_F32*>(src), dest,
- omx_spec_);
- CHECK_EQ(r, OMX_Sts_NoErr);
-}
-
} // namespace webrtc