Formalized Real 16-bit FFT for APM.
It also prepares for introducing Real 16-bit FFT Neon code from Openmax to SPL. CL https://webrtc-codereview.appspot.com/1819004/ takes care of that, but this CL is a prerequisite of that one. Tested audioproc with an offline file. Bit exact. R=andrew@webrtc.org, rtoy@google.com Review URL: https://webrtc-codereview.appspot.com/1830004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4390 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -13,70 +13,112 @@
|
||||
|
||||
#include "webrtc/typedefs.h"
|
||||
|
||||
// For ComplexFFT(), the maximum fft order is 10;
|
||||
// for OpenMax FFT in ARM, it is 12;
|
||||
// WebRTC APM uses orders of only 7 and 8.
|
||||
enum {kMaxFFTOrder = 10};
|
||||
|
||||
struct RealFFT;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct RealFFT* (*CreateRealFFT)(int order);
|
||||
typedef void (*FreeRealFFT)(struct RealFFT* self);
|
||||
typedef int (*RealForwardFFT)(struct RealFFT* self,
|
||||
const int16_t* data_in,
|
||||
int16_t* data_out);
|
||||
const int16_t* real_data_in,
|
||||
int16_t* complex_data_out);
|
||||
typedef int (*RealInverseFFT)(struct RealFFT* self,
|
||||
const int16_t* data_in,
|
||||
int16_t* data_out);
|
||||
const int16_t* complex_data_in,
|
||||
int16_t* real_data_out);
|
||||
|
||||
extern CreateRealFFT WebRtcSpl_CreateRealFFT;
|
||||
extern FreeRealFFT WebRtcSpl_FreeRealFFT;
|
||||
extern RealForwardFFT WebRtcSpl_RealForwardFFT;
|
||||
extern RealInverseFFT WebRtcSpl_RealInverseFFT;
|
||||
|
||||
struct RealFFT* WebRtcSpl_CreateRealFFT(int order);
|
||||
void WebRtcSpl_FreeRealFFT(struct RealFFT* self);
|
||||
struct RealFFT* WebRtcSpl_CreateRealFFTC(int order);
|
||||
void WebRtcSpl_FreeRealFFTC(struct RealFFT* self);
|
||||
|
||||
// TODO(kma): Implement FFT functions for real signals.
|
||||
#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
|
||||
struct RealFFT* WebRtcSpl_CreateRealFFTNeon(int order);
|
||||
void WebRtcSpl_FreeRealFFTNeon(struct RealFFT* self);
|
||||
#endif
|
||||
|
||||
// Compute the forward FFT for a complex signal of length 2^order.
|
||||
// Compute an FFT for a real-valued signal of length of 2^order,
|
||||
// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
|
||||
// specification structure, which must be initialized prior to calling the FFT
|
||||
// function with WebRtcSpl_CreateRealFFT().
|
||||
// The relationship between the input and output sequences can
|
||||
// be expressed in terms of the DFT, i.e.:
|
||||
// x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
|
||||
// n=0,1,2,...N-1
|
||||
// N=2^order.
|
||||
// The conjugate-symmetric output sequence is represented using a CCS vector,
|
||||
// which is of length N+2, and is organized as follows:
|
||||
// Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1
|
||||
// Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0
|
||||
// where R[n] and I[n], respectively, denote the real and imaginary components
|
||||
// for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length.
|
||||
// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
|
||||
// the foldover frequency.
|
||||
//
|
||||
// Input Arguments:
|
||||
// self - pointer to preallocated and initialized FFT specification structure.
|
||||
// data_in - the input signal.
|
||||
// real_data_in - the input signal. For an ARM Neon platform, it must be
|
||||
// aligned on a 32-byte boundary.
|
||||
//
|
||||
// Output Arguments:
|
||||
// data_out - the output signal; must be different to data_in.
|
||||
// complex_data_out - the output complex signal with (2^order + 2) 16-bit
|
||||
// elements. For an ARM Neon platform, it must be different
|
||||
// from real_data_in, and aligned on a 32-byte boundary.
|
||||
//
|
||||
// Return Value:
|
||||
// 0 - FFT calculation is successful.
|
||||
// -1 - Error
|
||||
//
|
||||
// -1 - Error with bad arguments (NULL pointers).
|
||||
int WebRtcSpl_RealForwardFFTC(struct RealFFT* self,
|
||||
const int16_t* data_in,
|
||||
int16_t* data_out);
|
||||
const int16_t* real_data_in,
|
||||
int16_t* complex_data_out);
|
||||
|
||||
#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
|
||||
int WebRtcSpl_RealForwardFFTNeon(struct RealFFT* self,
|
||||
const int16_t* data_in,
|
||||
int16_t* data_out);
|
||||
const int16_t* real_data_in,
|
||||
int16_t* complex_data_out);
|
||||
#endif
|
||||
|
||||
// Compute the inverse FFT for a complex signal of length 2^order.
|
||||
// Compute the inverse FFT for a conjugate-symmetric input sequence of length of
|
||||
// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
|
||||
// the specification structure, which must be initialized prior to calling the
|
||||
// FFT function with WebRtcSpl_CreateRealFFT().
|
||||
// For a transform of length M, the input sequence is represented using a packed
|
||||
// CCS vector of length M+2, which is explained in the comments for
|
||||
// WebRtcSpl_RealForwardFFTC above.
|
||||
//
|
||||
// Input Arguments:
|
||||
// self - pointer to preallocated and initialized FFT specification structure.
|
||||
// data_in - the input signal.
|
||||
// complex_data_in - the input complex signal with (2^order + 2) 16-bit
|
||||
// elements. For an ARM Neon platform, it must be aligned on
|
||||
// a 32-byte boundary.
|
||||
//
|
||||
// Output Arguments:
|
||||
// data_out - the output signal; must be different to data_in.
|
||||
// real_data_out - the output real signal. For an ARM Neon platform, it must
|
||||
// be different to complex_data_in, and aligned on a 32-byte
|
||||
// boundary.
|
||||
//
|
||||
// Return Value:
|
||||
// 0 or a positive number - a value that the elements in the |data_out| should
|
||||
// be shifted left with in order to get correct
|
||||
// physical values.
|
||||
// -1 - Error
|
||||
// 0 or a positive number - a value that the elements in the |real_data_out|
|
||||
// should be shifted left with in order to get
|
||||
// correct physical values.
|
||||
// -1 - Error with bad arguments (NULL pointers).
|
||||
int WebRtcSpl_RealInverseFFTC(struct RealFFT* self,
|
||||
const int16_t* data_in,
|
||||
int16_t* data_out);
|
||||
const int16_t* complex_data_in,
|
||||
int16_t* real_data_out);
|
||||
|
||||
#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
|
||||
int WebRtcSpl_RealInverseFFTNeon(struct RealFFT* self,
|
||||
const int16_t* data_in,
|
||||
int16_t* data_out);
|
||||
const int16_t* complex_data_in,
|
||||
int16_t* real_data_out);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user