Use inline wrappers to clarify forward/inverse FFTs

master
Chris Robinson 2020-09-13 04:18:40 -07:00
parent 9a883f5046
commit 0974b6b47c
5 changed files with 24 additions and 11 deletions

View File

@ -298,7 +298,7 @@ void ConvolutionState::setBuffer(const ALCdevice *device, const BufferStorage *b
done += todo;
std::fill(iter, fftbuffer->end(), complex_d{});
complex_fft(*fftbuffer, -1.0);
forward_fft(*fftbuffer);
filteriter = std::copy_n(fftbuffer->cbegin(), m, filteriter);
}
}
@ -418,7 +418,7 @@ void ConvolutionState::process(const size_t samplesToDo,
* frequency bins to the FFT history.
*/
std::copy_n(mInput.cbegin(), ConvolveUpdateSamples, mFftBuffer.begin());
complex_fft(mFftBuffer, -1.0);
forward_fft(mFftBuffer);
std::copy_n(mFftBuffer.begin(), m, &mComplexData[curseg*m]);
mFftBuffer.fill(complex_d{});
@ -453,7 +453,7 @@ void ConvolutionState::process(const size_t samplesToDo,
* second-half samples (and this output's second half is
* subsequently saved for next time).
*/
complex_fft(mFftBuffer, 1.0);
inverse_fft(mFftBuffer);
/* The iFFT'd response is scaled up by the number of bins, so apply
* the inverse to normalize the output.

View File

@ -169,7 +169,7 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float
*/
for(size_t k{0u};k < STFT_SIZE;k++)
mFftBuffer[k] = mFIFO[k] * HannWindow[k];
complex_fft(mFftBuffer, -1.0);
forward_fft(mFftBuffer);
/* Analyze the obtained data. Since the real FFT is symmetric, only
* STFT_HALF_SIZE+1 samples are needed.
@ -232,7 +232,7 @@ void PshifterState::process(const size_t samplesToDo, const al::span<const Float
/* Apply an inverse FFT to get the time-domain siganl, and accumulate
* for the output with windowing.
*/
complex_fft(mFftBuffer, 1.0);
inverse_fft(mFftBuffer);
for(size_t k{0u};k < STFT_SIZE;k++)
mOutputAccum[k] += HannWindow[k]*mFftBuffer[k].real() * (2.0/STFT_SIZE/OVERSAMP);

View File

@ -59,7 +59,7 @@ std::array<float,Uhj2Encoder::sFilterSize> GenerateFilter()
fftBuffer[half_size] = c0;
for(size_t i{half_size+1};i < fft_size;++i)
fftBuffer[i] = std::conj(fftBuffer[fft_size - i]);
complex_fft(fftBuffer, 1.0);
inverse_fft(fftBuffer);
/* Reverse and truncate the filter to a usable size, and store only the
* non-0 terms. Should this be windowed?

View File

@ -51,7 +51,7 @@ void complex_fft(const al::span<std::complex<double>> buffer, const double sign)
void complex_hilbert(const al::span<std::complex<double>> buffer)
{
complex_fft(buffer, 1.0);
inverse_fft(buffer);
const double inverse_size = 1.0/static_cast<double>(buffer.size());
auto bufiter = buffer.begin();
@ -65,5 +65,5 @@ void complex_hilbert(const al::span<std::complex<double>> buffer)
std::fill(bufiter, buffer.end(), std::complex<double>{});
complex_fft(buffer, -1.0);
forward_fft(buffer);
}

View File

@ -7,12 +7,25 @@
/**
* Iterative implementation of 2-radix FFT (In-place algorithm). Sign = -1 is
* FFT and 1 is iFFT (inverse). Fills the buffer with the Discrete Fourier
* Transform (DFT) of the time domain data stored in the buffer. The buffer is
* an array of complex numbers, and MUST BE power of two.
* 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);
/**
* 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); }
/**
* 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); }
/**
* Calculate the complex helical sequence (discrete-time analytical signal) of
* the given input using the discrete Hilbert transform (In-place algorithm).