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