1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
12#define WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
13
14#include "webrtc/typedefs.h"
15
16// For ComplexFFT(), the maximum fft order is 10;
17// for OpenMax FFT in ARM, it is 12;
18// WebRTC APM uses orders of only 7 and 8.
19enum {kMaxFFTOrder = 10};
20
21struct RealFFT;
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27struct RealFFT* WebRtcSpl_CreateRealFFT(int order);
28void WebRtcSpl_FreeRealFFT(struct RealFFT* self);
29
30// Compute an FFT for a real-valued signal of length of 2^order,
31// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
32// specification structure, which must be initialized prior to calling the FFT
33// function with WebRtcSpl_CreateRealFFT().
34// The relationship between the input and output sequences can
35// be expressed in terms of the DFT, i.e.:
36//     x[n] = (2^(-scalefactor)/N)  . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
37//     n=0,1,2,...N-1
38//     N=2^order.
39// The conjugate-symmetric output sequence is represented using a CCS vector,
40// which is of length N+2, and is organized as follows:
41//     Index:      0  1  2  3  4  5   . . .   N-2       N-1       N       N+1
42//     Component:  R0 0  R1 I1 R2 I2  . . .   R[N/2-1]  I[N/2-1]  R[N/2]  0
43// where R[n] and I[n], respectively, denote the real and imaginary components
44// for FFT bin 'n'. Bins  are numbered from 0 to N/2, where N is the FFT length.
45// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
46// the foldover frequency.
47//
48// Input Arguments:
49//   self - pointer to preallocated and initialized FFT specification structure.
50//   real_data_in - the input signal. For an ARM Neon platform, it must be
51//                  aligned on a 32-byte boundary.
52//
53// Output Arguments:
54//   complex_data_out - the output complex signal with (2^order + 2) 16-bit
55//                      elements. For an ARM Neon platform, it must be different
56//                      from real_data_in, and aligned on a 32-byte boundary.
57//
58// Return Value:
59//   0  - FFT calculation is successful.
60//   -1 - Error with bad arguments (NULL pointers).
61int WebRtcSpl_RealForwardFFT(struct RealFFT* self,
62                             const int16_t* real_data_in,
63                             int16_t* complex_data_out);
64
65// Compute the inverse FFT for a conjugate-symmetric input sequence of length of
66// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
67// the specification structure, which must be initialized prior to calling the
68// FFT function with WebRtcSpl_CreateRealFFT().
69// For a transform of length M, the input sequence is represented using a packed
70// CCS vector of length M+2, which is explained in the comments for
71// WebRtcSpl_RealForwardFFTC above.
72//
73// Input Arguments:
74//   self - pointer to preallocated and initialized FFT specification structure.
75//   complex_data_in - the input complex signal with (2^order + 2) 16-bit
76//                     elements. For an ARM Neon platform, it must be aligned on
77//                     a 32-byte boundary.
78//
79// Output Arguments:
80//   real_data_out - the output real signal. For an ARM Neon platform, it must
81//                   be different to complex_data_in, and aligned on a 32-byte
82//                   boundary.
83//
84// Return Value:
85//   0 or a positive number - a value that the elements in the |real_data_out|
86//                            should be shifted left with in order to get
87//                            correct physical values.
88//   -1 - Error with bad arguments (NULL pointers).
89int WebRtcSpl_RealInverseFFT(struct RealFFT* self,
90                             const int16_t* complex_data_in,
91                             int16_t* real_data_out);
92
93#ifdef __cplusplus
94}
95#endif
96
97#endif  // WEBRTC_COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
98