Im making a new project in which i want to boost some specific frequencies. To get a result i used FFT. I think my code is okay because when i display amplitude of some frequencies it seems to be correct. The problem starts when i want to test the plugin in AudioPluginHost. Audio is clliping.
I think it might be because of difference between buffer size and FFT vector size.
buffer_size = 480
FFT_vector_size = 1024
I have tried to change the FFT order but it didn’t make any difference. I know that the size of FFT vector should be twice bigger then buffer size.
How can i manipulate those two sizes to make it work?
The size of the FFT vector does not have to be twice the buffer size. If your buffer is 480, using a 512-length FFT is sufficient.
A common mistake is to not account for the negative frequencies. If you’re using the real-only transform (and you probably should) then you may only modify the first N / 2 + 1 elements from the FFT vector, where N is the FFT length.
Hi, thanks for quick response. So i set my arrays like that:
static constexpr auto fftOrder = 9 ;
buffer_size = 1 << fftOrder;
int fftHalfSize = buffer_size / 2+1;
Now that your buffer_size equals the FFT length, there is some stuff in your code that doesn’t need to happen (the std::fill and even the copy from fifo to fftData). But that’s not what’s causing this.
The buffer you pass into FFT.performRealOnlyForwardTransform must be twice as long, since it will need to store both the real and imaginary parts of the numbers! Maybe that’s what you meant in your original message with “I know that the size of FFT vector should be twice bigger then buffer size.” I guess my answer was a bit misleading there (the FFT length should equal the length of the input audio, but the actual memory buffer needs to be twice the FFT length).
So that’s probably the cause for the crash. It’s a little bit scary that this appears to use operator new but I’d have to see more of the stacktrace to say whether this is an issue or not.
P.S. The following should use fftHalfSize instead of buffer_size.
Thank you for your advice, so I have tried to make some changes as you suggested. But it doesnt seems to change anything, probably it’s my fault.
So right now I m using different audio interface so my buffer size is 441, but I think it s not a reason why it doesnt work. Sonow i m passing to FFT.performRealOnlyForwardTransform(f); a vector which has size 1024 and is half-fished as you said. I also added windowing, but it didnt help. I thought the rough sound is becouse of the changed amplitude of some frequencies, so I have tried without it and it didint help.
Maybe you see some mistake in my code that makes my sound clipping?
Or is there chance that clipping is caused by low code efficiency?
There is my code:
header file:
int fftHalfSize = buffer_size / 2+1;
std::array<float, buffer_size> fifo;
std::array<float, buffer_size*2> fftData;
float sizeMaxInv = (1.f / float(buffer_size - 1));
float sizeMaxInvPi = sizeMaxInv * juce::MathConstants<float>::pi;
int fifoIndex = 0;
float resolution = 1.f;
float m_sampleRate = 0;
float fundamentalFreq = 0;
int idx; /// bin's index
float max = 0.f; /// max amplitude of freq
float magnitude;
Well, after the FFT the contents of fftData are real, imag, real, imag, real, imag, ... in other words, interleaved complex numbers. You’re treating everything as real numbers, not as complex numbers.
You need to combine the real + imag parts to get the magnitude and phase, then change the magnitude, and finally convert the magnitude and phase back to real + imag parts. I also suggest reading up a bit on how the FFT works, that will clear up a lot of these questions.