1/*
2 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#ifndef AVCODEC_FFT_H
23#define AVCODEC_FFT_H
24
25#include <stdint.h>
26#include "config.h"
27#include "libavutil/mem.h"
28#include "avfft.h"
29
30/* FFT computation */
31
32struct FFTContext {
33    int nbits;
34    int inverse;
35    uint16_t *revtab;
36    FFTComplex *exptab;
37    FFTComplex *exptab1; /* only used by SSE code */
38    FFTComplex *tmp_buf;
39    int mdct_size; /* size of MDCT (i.e. number of input data * 2) */
40    int mdct_bits; /* n = 2^nbits */
41    /* pre/post rotation tables */
42    FFTSample *tcos;
43    FFTSample *tsin;
44    void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
45    void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
46    void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
47    void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
48    void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
49    int split_radix;
50    int permutation;
51#define FF_MDCT_PERM_NONE       0
52#define FF_MDCT_PERM_INTERLEAVE 1
53};
54
55#if CONFIG_HARDCODED_TABLES
56#define COSTABLE_CONST const
57#define SINTABLE_CONST const
58#define SINETABLE_CONST const
59#else
60#define COSTABLE_CONST
61#define SINTABLE_CONST
62#define SINETABLE_CONST
63#endif
64
65#define COSTABLE(size) \
66    COSTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_cos_##size)[size/2]
67#define SINTABLE(size) \
68    SINTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_sin_##size)[size/2]
69#define SINETABLE(size) \
70    SINETABLE_CONST DECLARE_ALIGNED(16, float, ff_sine_##size)[size]
71extern COSTABLE(16);
72extern COSTABLE(32);
73extern COSTABLE(64);
74extern COSTABLE(128);
75extern COSTABLE(256);
76extern COSTABLE(512);
77extern COSTABLE(1024);
78extern COSTABLE(2048);
79extern COSTABLE(4096);
80extern COSTABLE(8192);
81extern COSTABLE(16384);
82extern COSTABLE(32768);
83extern COSTABLE(65536);
84extern COSTABLE_CONST FFTSample* const ff_cos_tabs[17];
85
86/**
87 * Initializes the cosine table in ff_cos_tabs[index]
88 * \param index index in ff_cos_tabs array of the table to initialize
89 */
90void ff_init_ff_cos_tabs(int index);
91
92extern SINTABLE(16);
93extern SINTABLE(32);
94extern SINTABLE(64);
95extern SINTABLE(128);
96extern SINTABLE(256);
97extern SINTABLE(512);
98extern SINTABLE(1024);
99extern SINTABLE(2048);
100extern SINTABLE(4096);
101extern SINTABLE(8192);
102extern SINTABLE(16384);
103extern SINTABLE(32768);
104extern SINTABLE(65536);
105
106/**
107 * Sets up a complex FFT.
108 * @param nbits           log2 of the length of the input array
109 * @param inverse         if 0 perform the forward transform, if 1 perform the inverse
110 */
111int ff_fft_init(FFTContext *s, int nbits, int inverse);
112void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
113void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
114
115void ff_fft_init_altivec(FFTContext *s);
116void ff_fft_init_mmx(FFTContext *s);
117void ff_fft_init_arm(FFTContext *s);
118
119/**
120 * Do the permutation needed BEFORE calling ff_fft_calc().
121 */
122static inline void ff_fft_permute(FFTContext *s, FFTComplex *z)
123{
124    s->fft_permute(s, z);
125}
126/**
127 * Do a complex FFT with the parameters defined in ff_fft_init(). The
128 * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
129 */
130static inline void ff_fft_calc(FFTContext *s, FFTComplex *z)
131{
132    s->fft_calc(s, z);
133}
134void ff_fft_end(FFTContext *s);
135
136/* MDCT computation */
137
138static inline void ff_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
139{
140    s->imdct_calc(s, output, input);
141}
142static inline void ff_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
143{
144    s->imdct_half(s, output, input);
145}
146
147static inline void ff_mdct_calc(FFTContext *s, FFTSample *output,
148                                const FFTSample *input)
149{
150    s->mdct_calc(s, output, input);
151}
152
153/**
154 * Generate a Kaiser-Bessel Derived Window.
155 * @param   window  pointer to half window
156 * @param   alpha   determines window shape
157 * @param   n       size of half window
158 */
159void ff_kbd_window_init(float *window, float alpha, int n);
160
161/**
162 * Generate a sine window.
163 * @param   window  pointer to half window
164 * @param   n       size of half window
165 */
166void ff_sine_window_init(float *window, int n);
167
168/**
169 * initialize the specified entry of ff_sine_windows
170 */
171void ff_init_ff_sine_windows(int index);
172extern SINETABLE(  32);
173extern SINETABLE(  64);
174extern SINETABLE( 128);
175extern SINETABLE( 256);
176extern SINETABLE( 512);
177extern SINETABLE(1024);
178extern SINETABLE(2048);
179extern SINETABLE(4096);
180extern SINETABLE_CONST float * const ff_sine_windows[13];
181
182int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale);
183void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
184void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input);
185void ff_mdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
186void ff_mdct_end(FFTContext *s);
187
188/* Real Discrete Fourier Transform */
189
190struct RDFTContext {
191    int nbits;
192    int inverse;
193    int sign_convention;
194
195    /* pre/post rotation tables */
196    const FFTSample *tcos;
197    SINTABLE_CONST FFTSample *tsin;
198    FFTContext fft;
199    void (*rdft_calc)(struct RDFTContext *s, FFTSample *z);
200};
201
202/**
203 * Sets up a real FFT.
204 * @param nbits           log2 of the length of the input array
205 * @param trans           the type of transform
206 */
207int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans);
208void ff_rdft_end(RDFTContext *s);
209
210void ff_rdft_init_arm(RDFTContext *s);
211
212static av_always_inline void ff_rdft_calc(RDFTContext *s, FFTSample *data)
213{
214    s->rdft_calc(s, data);
215}
216
217/* Discrete Cosine Transform */
218
219struct DCTContext {
220    int nbits;
221    int inverse;
222    RDFTContext rdft;
223    const float *costab;
224    FFTSample *csc2;
225    void (*dct_calc)(struct DCTContext *s, FFTSample *data);
226};
227
228/**
229 * Sets up DCT.
230 * @param nbits           size of the input array:
231 *                        (1 << nbits)     for DCT-II, DCT-III and DST-I
232 *                        (1 << nbits) + 1 for DCT-I
233 *
234 * @note the first element of the input of DST-I is ignored
235 */
236int  ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type);
237void ff_dct_calc(DCTContext *s, FFTSample *data);
238void ff_dct_end (DCTContext *s);
239
240#endif /* AVCODEC_FFT_H */
241