0
votes

i have been trying to modify the amplitude for specific frequencies. Here is what i have done:

I get the data 2048 as float array which have a value range of [-1,1]. It's raw data.

I use this RealFFT algorithm http://www.lomont.org/Software/Misc/FFT/LomontFFT.html

I divide the raw data into left and right channel (this works great).

I perform RealFFT (forward enable) on both left and right and i use this equation to find which index is the right frequency that i want: freq/(samplerate/sizeOfBuffer/2.0)

I modify the frequency that i want.

I perform RealFFT (forward disable) to go back to frequency domain.

Now when i play back, i hear the change tat i did to the frequency but there is a flickering noise ( kinda the same flickering when you play an old vinyl song).

Any idea what i might do wrong? It was a while ago i took my signal processing course at my university so i might have forgot something.

Thanks in advance!

2
Are you sure you are only modifying the real part and not the imaginary part of the frequency bin? The imaginary part will affect the phase. the real & imaginary parts are interleaved so you'll need to multiply your integer index by 2 to get the real part, and add 1 to that to get the imaginary part.Pete
It doesn't sound right when i skip the imaginary partEqric
Are you doing this processing over the entire audio file, or are you chunking it up into buffers and putting the output back together? If the latter, you will need to perform overlap-save or similar method to maintain continuity at the buffer boundaries. See en.wikipedia.org/wiki/Overlap–save_method.Jason B
It's in real time, the sound engine provides me with a function in which will return a 2048 chunks into 'data' at a time. Its called every 23ms and returns 23ms worth of data at a time. Is it still necessary to perform overlap?Eqric

2 Answers

2
votes

The comments may be confusing. Here are some clarifications.

The imaginary part is not the phase. The real and imaginary parts form a vector, think of a 2-d plot where real is on the x axis and imaginary on the y. The amplitude of a frequency is the length of the line formed from the origin to the point. So, the phase is the arctan of the real and imaginary parts divided. The magnitude is the square root of the sum of squares of the real and imaginary parts.

So. The first step is that you want to change the magnitude of the vector, you must scale both the real and imaginary parts.

That's easy. The second part is much more complicated. The Fourier transform's "view" of the world is that it is infinitely periodic - that is, it looks like the signal wraps from the end, back to the beginning. If you put a perfect sine tone into your algorithm, and say that the period of the sine tone is 4096 samples. The first sample into the FFT is +1, then the last sample into the FFT is -1. If you look at the spectrum in the FFT, it will appear as if there are lots of high frequencies, which are the harmonics of transforming a signal that has a jump from -1 to 1. The longer and longer the FFT, the closer that the FFT shows you the "real" view of the signal.

Techniques to smooth out the transitions between FFT blocks have been developed, by windowing and overlapping the FFT blocks, so that the transitions between the blocks are not so "discontinuous". A fairly common technique is to use a Hann window and overlap by a factor of 4. That is, for every 2048 samples, you actually do 4 FFTs, and every FFT overlaps the previous block by 1536. The Hann window gets mathy, but basically it has nice properties so that you can do overlaps like this and everything sums up nicely.

I found this pretty fun blog showing exactly the same learning pains that you're going through: http://www.katjaas.nl/FFTwindow/FFTwindow&filtering.html

This technique is different from another commenter who mentions Overlap-Save. This is a a method developed to use FFTs to do FIR filtering. However, designing the FIR filter will typically be done in a mathematical package like Matlab/Octave.

1
votes

If you use a series of shorter FFTs to modify a longer signal, then one should zero-pad each window so that it uses a longer FFT (longer by the impulse response of the modification's spectrum), and combine the series of longer FFTs by overlap-add or overlap-save. Otherwise, waveform changes that should ripple past the end of each FFT/IFFT modification will , due to circular convolution, ripple around to the beginning of each window, and cause that periodic flickering distortion you hear.