aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/alcomplex.cpp18
-rw-r--r--common/alcomplex.h17
-rw-r--r--common/phase_shifter.h4
3 files changed, 26 insertions, 13 deletions
diff --git a/common/alcomplex.cpp b/common/alcomplex.cpp
index eae47227..c08ac751 100644
--- a/common/alcomplex.cpp
+++ b/common/alcomplex.cpp
@@ -91,7 +91,9 @@ constexpr std::array<al::span<const ushort2>,11> gBitReverses{{
} // namespace
-void complex_fft(const al::span<std::complex<double>> buffer, const double sign)
+template<typename Real>
+std::enable_if_t<std::is_floating_point<Real>::value>
+complex_fft(const al::span<std::complex<Real>> buffer, const Real sign)
{
const size_t fftsize{buffer.size()};
/* Get the number of bits used for indexing. Simplifies bit-reversal and
@@ -118,21 +120,21 @@ void complex_fft(const al::span<std::complex<double>> buffer, const double sign)
std::swap(buffer[rev.first], buffer[rev.second]);
/* Iterative form of Danielson-Lanczos lemma */
- const double pi{al::numbers::pi * sign};
+ const Real pi{al::numbers::pi_v<Real> * sign};
size_t step2{1u};
for(size_t i{0};i < log2_size;++i)
{
- const double arg{pi / static_cast<double>(step2)};
+ const Real arg{pi / static_cast<Real>(step2)};
/* TODO: Would std::polar(1.0, arg) be any better? */
- const std::complex<double> w{std::cos(arg), std::sin(arg)};
- std::complex<double> u{1.0, 0.0};
+ const std::complex<Real> w{std::cos(arg), std::sin(arg)};
+ std::complex<Real> u{1.0, 0.0};
const size_t step{step2 << 1};
for(size_t j{0};j < step2;j++)
{
for(size_t k{j};k < fftsize;k+=step)
{
- std::complex<double> temp{buffer[k+step2] * u};
+ std::complex<Real> temp{buffer[k+step2] * u};
buffer[k+step2] = buffer[k] - temp;
buffer[k] += temp;
}
@@ -163,3 +165,7 @@ void complex_hilbert(const al::span<std::complex<double>> buffer)
forward_fft(buffer);
}
+
+
+template void complex_fft<>(const al::span<std::complex<float>> buffer, const float sign);
+template void complex_fft<>(const al::span<std::complex<double>> buffer, const double sign);
diff --git a/common/alcomplex.h b/common/alcomplex.h
index 23b8114a..46dbb5bc 100644
--- a/common/alcomplex.h
+++ b/common/alcomplex.h
@@ -2,6 +2,7 @@
#define ALCOMPLEX_H
#include <complex>
+#include <type_traits>
#include "alspan.h"
@@ -10,21 +11,27 @@
* FFT and 1 is inverse FFT. Applies the Discrete Fourier Transform (DFT) to
* the data supplied in the buffer, which MUST BE power of two.
*/
-void complex_fft(const al::span<std::complex<double>> buffer, const double sign);
+template<typename Real>
+std::enable_if_t<std::is_floating_point<Real>::value>
+complex_fft(const al::span<std::complex<Real>> buffer, const Real sign);
/**
* Calculate the frequency-domain response of the time-domain signal in the
* provided buffer, which MUST BE power of two.
*/
-inline void forward_fft(const al::span<std::complex<double>> buffer)
-{ complex_fft(buffer, -1.0); }
+template<typename Real>
+std::enable_if_t<std::is_floating_point<Real>::value>
+forward_fft(const al::span<std::complex<Real>> buffer)
+{ complex_fft(buffer, Real{-1}); }
/**
* Calculate the time-domain signal of the frequency-domain response in the
* provided buffer, which MUST BE power of two.
*/
-inline void inverse_fft(const al::span<std::complex<double>> buffer)
-{ complex_fft(buffer, 1.0); }
+template<typename Real>
+std::enable_if_t<std::is_floating_point<Real>::value>
+inverse_fft(const al::span<std::complex<Real>> buffer)
+{ complex_fft(buffer, Real{1}); }
/**
* Calculate the complex helical sequence (discrete-time analytical signal) of
diff --git a/common/phase_shifter.h b/common/phase_shifter.h
index 83e07c7a..6cfdf053 100644
--- a/common/phase_shifter.h
+++ b/common/phase_shifter.h
@@ -53,12 +53,12 @@ struct PhaseShifterT {
std::fill_n(fftBuffer.get(), fft_size, complex_d{});
fftBuffer[half_size] = 1.0;
- forward_fft({fftBuffer.get(), fft_size});
+ forward_fft<double>({fftBuffer.get(), fft_size});
for(size_t i{0};i < half_size+1;++i)
fftBuffer[i] = complex_d{-fftBuffer[i].imag(), fftBuffer[i].real()};
for(size_t i{half_size+1};i < fft_size;++i)
fftBuffer[i] = std::conj(fftBuffer[fft_size - i]);
- inverse_fft({fftBuffer.get(), fft_size});
+ inverse_fft<double>({fftBuffer.get(), fft_size});
auto fftiter = fftBuffer.get() + half_size + (FilterSize/2 - 1);
for(float &coeff : mCoeffs)