4 * Copyright (C) 2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02111-1307, USA.
29 /// FFT routine copied from my old OneSignal library, modified to
30 /// match Calf's style. It's not fast at all, just a straightforward
32 template<class T
, int O
>
36 typedef typename
std::complex<T
> complex;
45 for (int i
=0; i
<N
; i
++)
48 for (int j
=0; j
<O
; j
++)
54 T divN
= 2 * M_PI
/ N
;
56 for (int i
=0; i
<N90
; i
++)
59 T c
= cos(angle
), s
= sin(angle
);
60 sines
[i
+ 3 * N90
] = -(sines
[i
+ N90
] = complex(-s
, c
));
61 sines
[i
+ 2 * N90
] = -(sines
[i
] = complex(c
, s
));
64 void calculate(complex *input
, complex *output
, bool inverse
) const
69 // Scramble the input data
75 complex &c
=input
[scramble
[i
]];
76 output
[i
]=mf
*complex(c
.imag(),c
.real());
81 output
[i
]=input
[scramble
[i
]];
86 int PO
=1<<i
, PNO
=1<<(O
-i
-1);
95 complex r1
=output
[B1
];
96 complex r2
=output
[B2
];
97 output
[B1
]=r1
+r2
*sines
[(B1
<<(O
-i
-1))&N1
];
98 output
[B2
]=r1
+r2
*sines
[(B2
<<(O
-i
-1))&N1
];
106 const complex &c
=output
[i
];
107 output
[i
]=complex(c
.imag(),c
.real());
111 template<class InType
>
112 void calculateN(InType
*input
, complex *output
, bool inverse
, int order
) const
119 // Scramble the input data
125 const complex &c
=input
[scramble
[i
] >> rsh
];
126 output
[i
]=mf
*complex(c
.imag(),c
.real());
131 output
[i
]=input
[scramble
[i
] >> rsh
];
134 for (i
=0; i
<order
; i
++)
136 int PO
=1<<i
, PNO
=1<<(order
-i
-1);
138 for (j
=0; j
<PNO
; j
++)
144 int B2
=base
+k
+(1<<i
);
145 complex r1
=output
[B1
];
146 complex r2
=output
[B2
];
147 output
[B1
]=r1
+r2
*sines
[(B1
<<(O
-i
-1))&N1
];
148 output
[B2
]=r1
+r2
*sines
[(B2
<<(O
-i
-1))&N1
];
156 const complex &c
=output
[i
];
157 output
[i
]=complex(c
.imag(),c
.real());
161 void execute_r2r(int order
, float *input
, float *output
, complex *tmp
, bool inverse
= false) const
163 calculateN
<float>(input
, tmp
, inverse
, order
);
164 size_t s
= 1 << order
;
165 size_t s2
= 1 << (order
- 1);
166 output
[0] = tmp
[0].real();
167 output
[s2
] = tmp
[0].imag();
168 for (size_t i
= 1; i
< s2
; ++i
)
170 output
[i
] = tmp
[i
].real();
171 output
[s
- 1 - i
] = tmp
[i
].imag();