8 extern inline ALcomplex
complex_add(ALcomplex a
, ALcomplex b
);
9 extern inline ALcomplex
complex_sub(ALcomplex a
, ALcomplex b
);
10 extern inline ALcomplex
complex_mult(ALcomplex a
, ALcomplex b
);
12 void complex_fft(ALcomplex
*FFTBuffer
, ALsizei FFTSize
, ALdouble Sign
)
14 ALsizei i
, j
, k
, mask
, step
, step2
;
18 /* Bit-reversal permutation applied to a sequence of FFTSize items */
19 for(i
= 1;i
< FFTSize
-1;i
++)
21 for(mask
= 0x1, j
= 0;mask
< FFTSize
;mask
<<= 1)
32 FFTBuffer
[i
] = FFTBuffer
[j
];
37 /* Iterative form of Danielson–Lanczos lemma */
38 for(i
= 1, step
= 2;i
< FFTSize
;i
<<=1, step
<<=1)
44 w
.Imag
= sin(arg
) * Sign
;
49 for(j
= 0;j
< step2
;j
++)
51 for(k
= j
;k
< FFTSize
;k
+=step
)
53 temp
= complex_mult(FFTBuffer
[k
+step2
], u
);
54 FFTBuffer
[k
+step2
] = complex_sub(FFTBuffer
[k
], temp
);
55 FFTBuffer
[k
] = complex_add(FFTBuffer
[k
], temp
);
58 u
= complex_mult(u
, w
);
63 void complex_hilbert(ALcomplex
*Buffer
, ALsizei size
)
65 const ALdouble inverse_size
= 1.0/(ALdouble
)size
;
68 for(i
= 0;i
< size
;i
++)
71 complex_fft(Buffer
, size
, 1.0);
74 Buffer
[0].Real
*= inverse_size
;
75 Buffer
[0].Imag
*= inverse_size
;
76 for(i
= 1;i
< todo
;i
++)
78 Buffer
[i
].Real
*= 2.0*inverse_size
;
79 Buffer
[i
].Imag
*= 2.0*inverse_size
;
81 Buffer
[i
].Real
*= inverse_size
;
82 Buffer
[i
].Imag
*= inverse_size
;
91 complex_fft(Buffer
, size
, -1.0);