annotate src/wma/libffwma/fft.c @ 3058:2e649bf16ebc

Robust media change handling written by John Wehle, closes bug #46.
author Tony Vroon <chainsaw@gentoo.org>
date Fri, 24 Apr 2009 09:23:20 +0100
parents 6b427677621f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
878
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
1 /*
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
2 * FFT/IFFT transforms
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
3 * Copyright (c) 2002 Fabrice Bellard.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
4 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
9 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
13 * Lesser General Public License for more details.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
14 *
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
18 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
19
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
20 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
21 * @file fft.c
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
22 * FFT/IFFT transforms.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
23 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
24
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
25 #include "dsputil.h"
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
26
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
27 #ifdef HAVE_ALTIVEC
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
28 #include <altivec.h>
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
29
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
30 #ifdef CONFIG_DARWIN
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
31 #include <sys/sysctl.h>
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
32 #else /* CONFIG_DARWIN */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
33 #include <signal.h>
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
34 #include <setjmp.h>
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
35
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
36 static sigjmp_buf jmpbuf;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
37 static volatile sig_atomic_t canjump = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
38
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
39 static void sigill_handler (int sig)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
40 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
41 if (!canjump) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
42 signal (sig, SIG_DFL);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
43 raise (sig);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
44 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
45
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
46 canjump = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
47 siglongjmp (jmpbuf, 1);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
48 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
49 #endif /* CONFIG_DARWIN */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
50
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
51
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
52 #define WORD_0 0x00,0x01,0x02,0x03
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
53 #define WORD_1 0x04,0x05,0x06,0x07
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
54 #define WORD_2 0x08,0x09,0x0a,0x0b
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
55 #define WORD_3 0x0c,0x0d,0x0e,0x0f
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
56 #define WORD_s0 0x10,0x11,0x12,0x13
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
57 #define WORD_s1 0x14,0x15,0x16,0x17
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
58 #define WORD_s2 0x18,0x19,0x1a,0x1b
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
59 #define WORD_s3 0x1c,0x1d,0x1e,0x1f
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
60
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
61 #ifdef CONFIG_DARWIN
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
62 #define vcprm(a,b,c,d) (const vector unsigned char)(WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
63 #else
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
64 #define vcprm(a,b,c,d) (const vector unsigned char){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d}
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
65 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
66
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
67 // vcprmle is used to keep the same index as in the SSE version.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
68 // it's the same as vcprm, with the index inversed
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
69 // ('le' is Little Endian)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
70 #define vcprmle(a,b,c,d) vcprm(d,c,b,a)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
71
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
72 // used to build inverse/identity vectors (vcii)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
73 // n is _n_egative, p is _p_ositive
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
74 #define FLOAT_n -1.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
75 #define FLOAT_p 1.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
76
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
77
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
78 #ifdef CONFIG_DARWIN
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
79 #define vcii(a,b,c,d) (const vector float)(FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
80 #else
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
81 #define vcii(a,b,c,d) (const vector float){FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d}
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
82 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
83
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
84 int has_altivec(void)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
85 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
86 #ifdef CONFIG_DARWIN
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
87 int sels[2] = {CTL_HW, HW_VECTORUNIT};
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
88 int has_vu = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
89 size_t len = sizeof(has_vu);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
90 int err;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
91
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
92 err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
93
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
94 if (err == 0) return (has_vu != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
95 #else /* CONFIG_DARWIN */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
96 /* no Darwin, do it the brute-force way */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
97 /* this is borrowed from the libmpeg2 library */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
98 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
99 signal (SIGILL, sigill_handler);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
100 if (sigsetjmp (jmpbuf, 1)) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
101 signal (SIGILL, SIG_DFL);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
102 } else {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
103 canjump = 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
104
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
105 __asm__ volatile ("mtspr 256, %0\n\t"
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
106 "vand %%v0, %%v0, %%v0"
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
107 :
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
108 : "r" (-1));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
109
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
110 signal (SIGILL, SIG_DFL);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
111 return 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
112 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
113 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
114 #endif /* CONFIG_DARWIN */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
115 return 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
116 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
117
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
118
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
119 void fft_calc_altivec(FFTContext *s, FFTComplex *z)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
120 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
121 #ifdef CONFIG_DARWIN
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
122 register const vector float vczero = (const vector float)(0.);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
123 #else
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
124 register const vector float vczero = (const vector float){0.,0.,0.,0.};
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
125 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
126
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
127 int ln = s->nbits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
128 int j, np, np2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
129 int nblocks, nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
130 register FFTComplex *p, *q;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
131 FFTComplex *cptr, *cptr1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
132 int k;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
133
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
134 np = 1 << ln;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
135
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
136 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
137 vector float *r, a, b, a1, c1, c2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
138
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
139 r = (vector float *)&z[0];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
140
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
141 c1 = vcii(p,p,n,n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
142
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
143 if (s->inverse)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
144 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
145 c2 = vcii(p,p,n,p);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
146 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
147 else
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
148 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
149 c2 = vcii(p,p,p,n);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
150 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
151
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
152 j = (np >> 2);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
153 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
154 a = vec_ld(0, r);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
155 a1 = vec_ld(sizeof(vector float), r);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
156
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
157 b = vec_perm(a,a,vcprmle(1,0,3,2));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
158 a = vec_madd(a,c1,b);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
159 /* do the pass 0 butterfly */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
160
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
161 b = vec_perm(a1,a1,vcprmle(1,0,3,2));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
162 b = vec_madd(a1,c1,b);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
163 /* do the pass 0 butterfly */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
164
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
165 /* multiply third by -i */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
166 b = vec_perm(b,b,vcprmle(2,3,1,0));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
167
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
168 /* do the pass 1 butterfly */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
169 vec_st(vec_madd(b,c2,a), 0, r);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
170 vec_st(vec_nmsub(b,c2,a), sizeof(vector float), r);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
171
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
172 r += 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
173 } while (--j != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
174 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
175 /* pass 2 .. ln-1 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
176
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
177 nblocks = np >> 3;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
178 nloops = 1 << 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
179 np2 = np >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
180
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
181 cptr1 = s->exptab1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
182 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
183 p = z;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
184 q = z + nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
185 j = nblocks;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
186 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
187 cptr = cptr1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
188 k = nloops >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
189 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
190 vector float a,b,c,t1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
191
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
192 a = vec_ld(0, (float*)p);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
193 b = vec_ld(0, (float*)q);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
194
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
195 /* complex mul */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
196 c = vec_ld(0, (float*)cptr);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
197 /* cre*re cim*re */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
198 t1 = vec_madd(c, vec_perm(b,b,vcprmle(2,2,0,0)),vczero);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
199 c = vec_ld(sizeof(vector float), (float*)cptr);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
200 /* -cim*im cre*im */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
201 b = vec_madd(c, vec_perm(b,b,vcprmle(3,3,1,1)),t1);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
202
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
203 /* butterfly */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
204 vec_st(vec_add(a,b), 0, (float*)p);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
205 vec_st(vec_sub(a,b), 0, (float*)q);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
206
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
207 p += 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
208 q += 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
209 cptr += 4;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
210 } while (--k);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
211
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
212 p += nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
213 q += nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
214 } while (--j);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
215 cptr1 += nloops * 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
216 nblocks = nblocks >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
217 nloops = nloops << 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
218 } while (nblocks != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
219 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
220
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
221 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
222
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
223 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
224 * The size of the FFT is 2^nbits. If inverse is TRUE, inverse FFT is
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
225 * done
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
226 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
227 int fft_inits(FFTContext *s, int nbits, int inverse)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
228 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
229 int i, j, m, n;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
230 float alpha, c1, s1, s2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
231
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
232 s->nbits = nbits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
233 n = 1 << nbits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
234
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
235 s->exptab = av_malloc((n / 2) * sizeof(FFTComplex));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
236 if (!s->exptab)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
237 goto fail;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
238 s->revtab = av_malloc(n * sizeof(uint16_t));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
239 if (!s->revtab)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
240 goto fail;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
241 s->inverse = inverse;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
242
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
243 s2 = inverse ? 1.0 : -1.0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
244
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
245 for(i=0;i<(n/2);i++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
246 alpha = 2 * M_PI * (float)i / (float)n;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
247 c1 = cos(alpha);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
248 s1 = sin(alpha) * s2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
249 s->exptab[i].re = c1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
250 s->exptab[i].im = s1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
251 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
252 s->fft_calc = fft_calc_c;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
253 s->exptab1 = NULL;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
254 /* compute constant table for HAVE_SSE version */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
255 #if (defined(HAVE_ALTIVEC))
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
256 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
257 int has_vectors = 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
258
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
259 #if defined(HAVE_ALTIVEC)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
260 has_vectors = has_altivec();
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
261 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
262 if (has_vectors) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
263 int np, nblocks, np2, l;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
264 FFTComplex *q;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
265
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
266 np = 1 << nbits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
267 nblocks = np >> 3;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
268 np2 = np >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
269 s->exptab1 = av_malloc(np * 2 * sizeof(FFTComplex));
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
270 if (!s->exptab1)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
271 goto fail;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
272 q = s->exptab1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
273 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
274 for(l = 0; l < np2; l += 2 * nblocks) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
275 *q++ = s->exptab[l];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
276 *q++ = s->exptab[l + nblocks];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
277
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
278 q->re = -s->exptab[l].im;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
279 q->im = s->exptab[l].re;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
280 q++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
281 q->re = -s->exptab[l + nblocks].im;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
282 q->im = s->exptab[l + nblocks].re;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
283 q++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
284 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
285 nblocks = nblocks >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
286 } while (nblocks != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
287 av_freep(&s->exptab);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
288 s->fft_calc = fft_calc_altivec;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
289 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
290 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
291 #endif
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
292
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
293 /* compute bit reverse table */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
294
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
295 for(i=0;i<n;i++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
296 m=0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
297 for(j=0;j<nbits;j++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
298 m |= ((i >> j) & 1) << (nbits-j-1);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
299 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
300 s->revtab[i]=m;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
301 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
302 return 0;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
303 fail:
2321
6b427677621f killed a few warnings
Cristi Magherusan <majeru@atheme.org>
parents: 1951
diff changeset
304 av_freep((void*)&s->revtab);
6b427677621f killed a few warnings
Cristi Magherusan <majeru@atheme.org>
parents: 1951
diff changeset
305 av_freep((void*)&s->exptab);
6b427677621f killed a few warnings
Cristi Magherusan <majeru@atheme.org>
parents: 1951
diff changeset
306 av_freep((void*)&s->exptab1);
878
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
307 return -1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
308 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
309
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
310 /* butter fly op */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
311 #define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
312 {\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
313 FFTSample ax, ay, bx, by;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
314 bx=pre1;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
315 by=pim1;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
316 ax=qre1;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
317 ay=qim1;\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
318 pre = (bx + ax);\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
319 pim = (by + ay);\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
320 qre = (bx - ax);\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
321 qim = (by - ay);\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
322 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
323
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
324 #define MUL16(a,b) ((a) * (b))
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
325
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
326 #define CMUL(pre, pim, are, aim, bre, bim) \
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
327 {\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
328 pre = (MUL16(are, bre) - MUL16(aim, bim));\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
329 pim = (MUL16(are, bim) + MUL16(bre, aim));\
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
330 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
331
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
332 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
333 * Do a complex FFT with the parameters defined in fft_init(). The
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
334 * input data must be permuted before with s->revtab table. No
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
335 * 1.0/sqrt(n) normalization is done.
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
336 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
337 void fft_calc_c(FFTContext *s, FFTComplex *z)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
338 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
339 int ln = s->nbits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
340 int j, np, np2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
341 int nblocks, nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
342 register FFTComplex *p, *q;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
343 FFTComplex *exptab = s->exptab;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
344 int l;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
345 FFTSample tmp_re, tmp_im;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
346
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
347 np = 1 << ln;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
348
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
349 /* pass 0 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
350
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
351 p=&z[0];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
352 j=(np >> 1);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
353 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
354 BF(p[0].re, p[0].im, p[1].re, p[1].im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
355 p[0].re, p[0].im, p[1].re, p[1].im);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
356 p+=2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
357 } while (--j != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
358
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
359 /* pass 1 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
360
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
361
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
362 p=&z[0];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
363 j=np >> 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
364 if (s->inverse) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
365 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
366 BF(p[0].re, p[0].im, p[2].re, p[2].im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
367 p[0].re, p[0].im, p[2].re, p[2].im);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
368 BF(p[1].re, p[1].im, p[3].re, p[3].im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
369 p[1].re, p[1].im, -p[3].im, p[3].re);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
370 p+=4;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
371 } while (--j != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
372 } else {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
373 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
374 BF(p[0].re, p[0].im, p[2].re, p[2].im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
375 p[0].re, p[0].im, p[2].re, p[2].im);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
376 BF(p[1].re, p[1].im, p[3].re, p[3].im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
377 p[1].re, p[1].im, p[3].im, -p[3].re);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
378 p+=4;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
379 } while (--j != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
380 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
381 /* pass 2 .. ln-1 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
382
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
383 nblocks = np >> 3;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
384 nloops = 1 << 2;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
385 np2 = np >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
386 do {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
387 p = z;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
388 q = z + nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
389 for (j = 0; j < nblocks; ++j) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
390 BF(p->re, p->im, q->re, q->im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
391 p->re, p->im, q->re, q->im);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
392
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
393 p++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
394 q++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
395 for(l = nblocks; l < np2; l += nblocks) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
396 CMUL(tmp_re, tmp_im, exptab[l].re, exptab[l].im, q->re, q->im);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
397 BF(p->re, p->im, q->re, q->im,
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
398 p->re, p->im, tmp_re, tmp_im);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
399 p++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
400 q++;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
401 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
402
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
403 p += nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
404 q += nloops;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
405 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
406 nblocks = nblocks >> 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
407 nloops = nloops << 1;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
408 } while (nblocks != 0);
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
409 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
410
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
411 /**
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
412 * Do the permutation needed BEFORE calling fft_calc()
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
413 */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
414 void fft_permute(FFTContext *s, FFTComplex *z)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
415 {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
416 int j, k, np;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
417 FFTComplex tmp;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
418 const uint16_t *revtab = s->revtab;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
419
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
420 /* reverse */
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
421 np = 1 << s->nbits;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
422 for(j=0;j<np;j++) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
423 k = revtab[j];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
424 if (k < j) {
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
425 tmp = z[k];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
426 z[k] = z[j];
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
427 z[j] = tmp;
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
428 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
429 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
430 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
431
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
432 void fft_end(FFTContext *s)
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
433 {
2321
6b427677621f killed a few warnings
Cristi Magherusan <majeru@atheme.org>
parents: 1951
diff changeset
434 av_freep((void*)&s->revtab);
6b427677621f killed a few warnings
Cristi Magherusan <majeru@atheme.org>
parents: 1951
diff changeset
435 av_freep((void*)&s->exptab);
6b427677621f killed a few warnings
Cristi Magherusan <majeru@atheme.org>
parents: 1951
diff changeset
436 av_freep((void*)&s->exptab1);
878
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
437 }
aa044d71838f [svn] Goodbye ffmpeg, welcome back WMA.
chainsaw
parents:
diff changeset
438