11 #include "math_defs.h"
14 void complex_fft(const al::span
<std::complex<double>> buffer
, const double sign
)
16 const size_t fftsize
{buffer
.size()};
17 /* Bit-reversal permutation applied to a sequence of FFTSize items */
18 for(size_t i
{1u};i
< fftsize
-1;i
++)
21 for(size_t mask
{1u};mask
< fftsize
;mask
<<= 1)
30 std::swap(buffer
[i
], buffer
[j
]);
33 /* Iterative form of Danielson–Lanczos lemma */
35 for(size_t i
{1u};i
< fftsize
;i
<<=1, step
<<=1)
37 const size_t step2
{step
>> 1};
38 double arg
{al::MathDefs
<double>::Pi() / static_cast<double>(step2
)};
40 std::complex<double> w
{std::cos(arg
), std::sin(arg
)*sign
};
41 std::complex<double> u
{1.0, 0.0};
42 for(size_t j
{0};j
< step2
;j
++)
44 for(size_t k
{j
};k
< fftsize
;k
+=step
)
46 std::complex<double> temp
{buffer
[k
+step2
] * u
};
47 buffer
[k
+step2
] = buffer
[k
] - temp
;
56 void complex_hilbert(const al::span
<std::complex<double>> buffer
)
58 complex_fft(buffer
, 1.0);
60 const double inverse_size
= 1.0/static_cast<double>(buffer
.size());
61 auto bufiter
= buffer
.begin();
62 const auto halfiter
= bufiter
+ (buffer
.size()>>1);
64 *bufiter
*= inverse_size
; ++bufiter
;
65 bufiter
= std::transform(bufiter
, halfiter
, bufiter
,
66 [inverse_size
](const std::complex<double> &c
) -> std::complex<double>
67 { return c
* (2.0*inverse_size
); });
68 *bufiter
*= inverse_size
; ++bufiter
;
70 std::fill(bufiter
, buffer
.end(), std::complex<double>{});
72 complex_fft(buffer
, -1.0);