[copy+pasted from Reddit]
Okay, so I have JUCE, which has it’s own FFT class. I (think) I understand the basics of FFT algorithms. Here’s what I ‘know’, and my questions regarding these ‘knowings’:
1. FFT’s turn amplitude/time into frequency/magnitude, but FFT algorithms take ‘Complex’ numbers (with real/imaginary parts) as parameters.
From what I understand, what the FFT spits out is basically an (x,y) coordinate. I know that it’s not actually called x y, and is actually called real imaginary, but that’s how I think of it. Calculating the distance (a2 + b2 =c2) gives you the magnitude (volume) of the bin, and calculating the angle (atan(y/x)) gives you the phase of the bin… (right?).
- How to I go from my input samples to these complex number inputs?
- Do I arrange my data in the array so that every even index has a sample, and every odd is blank?
- Furthermore, do I have to convert from ‘samples’ to ‘complexes’ somehow before I FFT? I can’t imagine what that even means or how to do it
Is the output arranged like a pattern like:
[r, i, r, i, r,…]
or is it
[r, r, r, r, … i,i,i,i]
2. Once you’ve FFT’d, you can modify this spectral data, then iFFT back to amplitude/time.
Can someone explain to me why if I zero the first 257 samples of a 2048 size FFT, instead of a steep hi-pass filter, I’m left with a -6dB shelf?
I’m going to pseudo type my FFT code here - let me know if there are any glaringly obvious mistakes:
header
class MyFFT
{
public:
void FFT_Test(float * const, int);
juce::FFT myfft[2];
std::vectorFFT::Complex inputFFT;
std::vectorFFT::Complex scratchFFT;
std::vectorFFT::Complex outputFFT;
int i_fft;
};
source
// 2048-sized FFT/iFFT ...
myfft[0] = new juce::FFT(11, forward); //11th power, forward
myfft[1] = new juce::FFT(11, inverse); //11th power, inverse
// 2048-sized complex vector (as requested by juce::FFT)
inputFFT.resize(2048)
scratchFFT.resize(2048);
outputFFT.resize(2048)
void FFT_Test (float * const samples, int sampleCount)
{
for(int i = 0; i < sampleCount; ++i)
{
float in = samples[i];
samples[i] = output[i_fft]; // output FFT'd samples
inputFFT[i_fft].r = in; // input new samples.... set real = sample .... ? ....
i_fft = (i_fft + 1) % fft_size; // == 2048
if(i_fft == 0)
{
// forward FFT ...
myfft[0]->perform(&inputFFT[0], &scratchFFT[0]);
const int hipassindex = 256;
// hipass filter wannabe - only drops 6dB
// (hipassindex +1) to also zero the 'imaginary' ... ? ....
memset(&scratchFFT[0], 0, sizeof(float) * (hipassindex +1));
// inverseFFT ...
myfft[1]->perform(&scratchFFT[0], &outputFFT[0]);
}
}
}