]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_srfft.c
22e56774f711503eec7986aa80a888ec028c39ee
[vlc] / src / ac3_decoder / ac3_srfft.c
1 #include "defs.h"
2
3 #include <math.h>
4 #include <stdio.h>
5
6 #include "config.h"
7 #include "common.h"
8 #include "threads.h"
9 #include "mtime.h"
10
11 #include "stream_control.h"
12 #include "input_ext-dec.h"
13
14 #include "ac3_decoder.h"
15 #include "ac3_srfft.h"
16
17 void fft_8 (complex_t *x);
18
19 void fft_4(complex_t *x)
20 {
21   /* delta_p = 1 here */
22   /* x[k] = sum_{i=0..3} x[i] * w^{i*k}, w=e^{-2*pi/4} 
23    */
24
25   register float yt_r, yt_i, yb_r, yb_i, u_r, u_i, vi_r, vi_i;
26   
27   yt_r = x[0].real;
28   yb_r = yt_r - x[2].real;
29   yt_r += x[2].real;
30
31   u_r = x[1].real;
32   vi_i = x[3].real - u_r;
33   u_r += x[3].real;
34   
35   u_i = x[1].imag;
36   vi_r = u_i - x[3].imag;
37   u_i += x[3].imag;
38
39   yt_i = yt_r;
40   yt_i += u_r;
41   x[0].real = yt_i;
42   yt_r -= u_r;
43   x[2].real = yt_r;
44   yt_i = yb_r;
45   yt_i += vi_r;
46   x[1].real = yt_i;
47   yb_r -= vi_r;
48   x[3].real = yb_r;
49
50   yt_i = x[0].imag;
51   yb_i = yt_i - x[2].imag;
52   yt_i += x[2].imag;
53
54   yt_r = yt_i;
55   yt_r += u_i;
56   x[0].imag = yt_r;
57   yt_i -= u_i;
58   x[2].imag = yt_i;
59   yt_r = yb_i;
60   yt_r += vi_i;
61   x[1].imag = yt_r;
62   yb_i -= vi_i;
63   x[3].imag = yb_i;
64 }
65
66
67 void fft_8 (complex_t *x)
68 {
69   /* delta_p = diag{1, sqrt(i)} here */
70   /* x[k] = sum_{i=0..7} x[i] * w^{i*k}, w=e^{-2*pi/8} 
71    */
72   register float wT1_r, wT1_i, wB1_r, wB1_i, wT2_r, wT2_i, wB2_r, wB2_i;
73   
74   wT1_r = x[1].real;
75   wT1_i = x[1].imag;
76   wB1_r = x[3].real;
77   wB1_i = x[3].imag;
78
79   x[1] = x[2];
80   x[2] = x[4];
81   x[3] = x[6];
82   fft_4(&x[0]);
83
84   
85   /* x[0] x[4] */
86   wT2_r = x[5].real;
87   wT2_r += x[7].real;
88   wT2_r += wT1_r;
89   wT2_r += wB1_r;
90   wT2_i = wT2_r;
91   wT2_r += x[0].real;
92   wT2_i = x[0].real - wT2_i;
93   x[0].real = wT2_r;
94   x[4].real = wT2_i;
95
96   wT2_i = x[5].imag;
97   wT2_i += x[7].imag;
98   wT2_i += wT1_i;
99   wT2_i += wB1_i;
100   wT2_r = wT2_i;
101   wT2_r += x[0].imag;
102   wT2_i = x[0].imag - wT2_i;
103   x[0].imag = wT2_r;
104   x[4].imag = wT2_i;
105   
106   /* x[2] x[6] */
107   wT2_r = x[5].imag;
108   wT2_r -= x[7].imag;
109   wT2_r += wT1_i;
110   wT2_r -= wB1_i;
111   wT2_i = wT2_r;
112   wT2_r += x[2].real;
113   wT2_i = x[2].real - wT2_i;
114   x[2].real = wT2_r;
115   x[6].real = wT2_i;
116
117   wT2_i = x[5].real;
118   wT2_i -= x[7].real;
119   wT2_i += wT1_r;
120   wT2_i -= wB1_r;
121   wT2_r = wT2_i;
122   wT2_r += x[2].imag;
123   wT2_i = x[2].imag - wT2_i;
124   x[2].imag = wT2_i;
125   x[6].imag = wT2_r;
126   
127
128   /* x[1] x[5] */
129   wT2_r = wT1_r;
130   wT2_r += wB1_i;
131   wT2_r -= x[5].real;
132   wT2_r -= x[7].imag;
133   wT2_i = wT1_i;
134   wT2_i -= wB1_r;
135   wT2_i -= x[5].imag;
136   wT2_i += x[7].real;
137
138   wB2_r = wT2_r;
139   wB2_r += wT2_i;
140   wT2_i -= wT2_r;
141   wB2_r *= HSQRT2;
142   wT2_i *= HSQRT2;
143   wT2_r = wB2_r;
144   wB2_r += x[1].real;
145   wT2_r =  x[1].real - wT2_r;
146
147   wB2_i = x[5].real;
148   x[1].real = wB2_r;
149   x[5].real = wT2_r;
150
151   wT2_r = wT2_i;
152   wT2_r += x[1].imag;
153   wT2_i = x[1].imag - wT2_i;
154   wB2_r = x[5].imag;
155   x[1].imag = wT2_r;
156   x[5].imag = wT2_i;
157
158   /* x[3] x[7] */
159   wT1_r -= wB1_i;
160   wT1_i += wB1_r;
161   wB1_r = wB2_i - x[7].imag;
162   wB1_i = wB2_r + x[7].real;
163   wT1_r -= wB1_r;
164   wT1_i -= wB1_i;
165   wB1_r = wT1_r + wT1_i;
166   wB1_r *= HSQRT2;
167   wT1_i -= wT1_r;
168   wT1_i *= HSQRT2;
169   wB2_r = x[3].real;
170   wB2_i = wB2_r + wT1_i;
171   wB2_r -= wT1_i;
172   x[3].real = wB2_i;
173   x[7].real = wB2_r;
174   wB2_i = x[3].imag;
175   wB2_r = wB2_i + wB1_r;
176   wB2_i -= wB1_r;
177   x[3].imag = wB2_i;
178   x[7].imag = wB2_r;
179 }
180
181
182 void fft_asmb(int k, complex_t *x, complex_t *wTB,
183              const complex_t *d, const complex_t *d_3)
184 {
185   register complex_t  *x2k, *x3k, *x4k, *wB;
186   register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
187
188   x2k = x + 2 * k;
189   x3k = x2k + 2 * k;
190   x4k = x3k + 2 * k;
191   wB = wTB + 2 * k;
192   
193   TRANSZERO(x[0],x2k[0],x3k[0],x4k[0]);
194   TRANS(x[1],x2k[1],x3k[1],x4k[1],wTB[1],wB[1],d[1],d_3[1]);
195   
196   --k;
197   for(;;) {
198      TRANS(x[2],x2k[2],x3k[2],x4k[2],wTB[2],wB[2],d[2],d_3[2]);
199      TRANS(x[3],x2k[3],x3k[3],x4k[3],wTB[3],wB[3],d[3],d_3[3]);
200      if (!--k) break;
201      x += 2;
202      x2k += 2;
203      x3k += 2;
204      x4k += 2;
205      d += 2;
206      d_3 += 2;
207      wTB += 2;
208      wB += 2;
209   }
210  
211 }
212
213 void fft_asmb16(complex_t *x, complex_t *wTB)
214 {
215   register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
216   int k = 2;
217
218   /* transform x[0], x[8], x[4], x[12] */
219   TRANSZERO(x[0],x[4],x[8],x[12]);
220
221   /* transform x[1], x[9], x[5], x[13] */
222   TRANS(x[1],x[5],x[9],x[13],wTB[1],wTB[5],delta16[1],delta16_3[1]);
223
224   /* transform x[2], x[10], x[6], x[14] */
225   TRANSHALF_16(x[2],x[6],x[10],x[14]);
226
227   /* transform x[3], x[11], x[7], x[15] */
228   TRANS(x[3],x[7],x[11],x[15],wTB[3],wTB[7],delta16[3],delta16_3[3]);
229
230
231
232
233 void fft_64p_c (complex_t *a)
234 {
235   fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
236   fft_asmb16(&a[0], &a[8]);
237   
238   fft_8(&a[16]), fft_8(&a[24]);
239   fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
240
241   fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]);
242   fft_asmb16(&a[32], &a[40]);
243
244   fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]);
245   fft_asmb16(&a[48], &a[56]);
246
247   fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
248 }
249
250
251 void fft_128p_c (complex_t *a)
252 {
253   fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
254   fft_asmb16(&a[0], &a[8]);
255   
256   fft_8(&a[16]), fft_8(&a[24]);
257   fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
258
259   fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]);
260   fft_asmb16(&a[32], &a[40]);
261
262   fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]);
263   fft_asmb16(&a[48], &a[56]);
264
265   fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
266
267   fft_8(&a[64]); fft_4(&a[72]); fft_4(&a[76]);
268   /* fft_16(&a[64]); */
269   fft_asmb16(&a[64], &a[72]);
270
271   fft_8(&a[80]); fft_8(&a[88]);
272   
273   /* fft_32(&a[64]); */
274   fft_asmb(4, &a[64], &a[80],&delta32[0], &delta32_3[0]);
275
276   fft_8(&a[96]); fft_4(&a[104]), fft_4(&a[108]);
277   /* fft_16(&a[96]); */
278   fft_asmb16(&a[96], &a[104]);
279
280   fft_8(&a[112]), fft_8(&a[120]);
281   /* fft_32(&a[96]); */
282   fft_asmb(4, &a[96], &a[112], &delta32[0], &delta32_3[0]);
283   
284   /* fft_128(&a[0]); */
285   fft_asmb(16, &a[0], &a[64], &delta128[0], &delta128_3[0]);
286 }