Hi, I have an FFT question related to spectral leakage between bins... Setup: I am investigating the use of an FFT as a channelizer. I apply no window (i.e. rectangular) and take each bin to be one of my channelizer output channels. The tone is not located at the center of a bin. Result: As I expect, I see spectral leakage between bins. What I don't understand is why the signal in the adjacent bins is at the exact same frequency as in the main bin (with lower amplitude). I realize that with an unwindowed FFT their is overlap between the adjacent bins, but shouldn't the frequency shift when I move a bin in either direction away from the main bin? Any help would be greatly appeciated!
FFT Bin Spectral Leakage
Started by ●August 25, 2009
Reply by ●August 25, 20092009-08-25
On Aug 25, 8:17�am, "jah" <andy.harri...@unb.ca> wrote:> Hi, > > I have an FFT question related to spectral leakage between bins... > > Setup: > > I am investigating the use of an FFT as a channelizer. I apply no window > (i.e. rectangular) and take each bin to be one of my channelizer output > channels. The tone is not located at the center of a bin. > > Result: > > As I expect, I see spectral leakage between bins. What I don't understand > is why the signal in the adjacent bins is at the exact same frequency as in > the main bin (with lower amplitude). I realize that with an unwindowed FFT > their is overlap between the adjacent bins, but shouldn't the frequency > shift when I move a bin in either direction away from the main bin? > > Any help would be greatly appeciated!basically each bin is reporting a sinx/x frequency response of a tone that each bin sees shifted a different amount
Reply by ●August 25, 20092009-08-25
On Tue, 25 Aug 2009 07:17:30 -0500, "jah" <andy.harriman@unb.ca> wrote:>Hi, > >I have an FFT question related to spectral leakage between bins... > >Setup: > >I am investigating the use of an FFT as a channelizer. I apply no window >(i.e. rectangular) and take each bin to be one of my channelizer output >channels. The tone is not located at the center of a bin. > >Result: > >As I expect, I see spectral leakage between bins. What I don't understand >is why the signal in the adjacent bins is at the exact same frequency as in >the main bin (with lower amplitude). I realize that with an unwindowed FFT >their is overlap between the adjacent bins, but shouldn't the frequency >shift when I move a bin in either direction away from the main bin? > >Any help would be greatly appeciated!Hi jah, Wow, your question is strange. I don't understand it. For an N-point FFT, of data samples whose sample rate is Fs samples/second, the output of the FFT's (for example) 7th bin is proportional to the signal's total spectral energy under a sin(x)/x curve centered at 6*Fs/N. The output of the FFT's 8th bin is proportional to the signal's total spectral energy under a sin(x)/x curve centered at 7*Fs/N. So the notion (the idea, the thought) that a signal's frequency is the same in two different FFT bins does not make sense. What you should say is that a signal's spectral energy is non-zero (the energy "shows up") in the 7th bin *and* the 8th bin. Hope that made some sort of sense. Good Luck, [-Rick-]
Reply by ●August 26, 20092009-08-26
Hi Guys, Thanks for your input. I realize my question may not make much sense :) Let me try again... My end goal is to design an FFT-based channelizer (e.g. polyphase FFT, or WOLA). Initially, I am starting with a simple FFT so that I can get a solid understanding of what I am working with. I am trying to build from the following FFT property: "It converts a block of N time samples equally spaced in time into block of N frequency samples equally spaced in frequency. For a continuous stream of input time sample blocks, samples at a given point in successive output blocks represent a translated, bandpass frequency signal or bin." reference: http://www.pentek.com/tutorials/15_4/digdown.cfm My test: In Matlab, I am generating a pure tone of a particular frequency (not centered perfectly on a bin), f1, of length, L, using my sample frequency, fs. I then process the tone in a blockwise fashion (with no overlap between blocks) using an N-point FFT. The result is a number of samples (L/N) for each "bin". The spacing between bins is fs/N, and the sample rate per per bin is fs/N. When I then plot my time-domain samples for each bin, what I am seeing is that the tone appears in several adjacent bins. For example, if most of the power is in bin X, there will also be some in bin X+1, X-1, and so on... This I expect. What I don't understand is why when I plot the FFT of the time-domain data from bins X and X+1, the tone appears at the same location in the FFT output of both (X+1 has lower power). I hope this makes more sense :)
Reply by ●August 26, 20092009-08-26
On 26 Aug, 13:31, "jah" <andy.harri...@unb.ca> wrote:> Hi Guys, > > Thanks for your input. I realize my question may not make much sense :) > Let me try again... > > My end goal is to design an FFT-based channelizer (e.g. polyphase FFT, or > WOLA). Initially, I am starting with a simple FFT so that I can get a solid > understanding of what I am working with. > > I am trying to build from the following FFT property: > > "It converts a block of N time samples equally spaced in time into block > of N frequency samples equally spaced in frequency. For a continuous stream > of input time sample blocks, samples at a given point in successive output > blocks represent a translated, bandpass frequency signal or bin." > reference:http://www.pentek.com/tutorials/15_4/digdown.cfmThis doesn't make sense to me.> My test: > > In Matlab, I am generating a pure tone of a particular frequency (not > centered perfectly on a bin), f1, of length, L, using my sample frequency, > fs. I then process the tone in a blockwise fashion (with no overlap between > blocks) using an N-point FFT. The result is a number of samples (L/N) for > each "bin". The spacing between bins is fs/N, and the sample rate per per > bin is fs/N. > > When I then plot my time-domain samples for each bin, what I am seeing is > that the tone appears in several adjacent bins. For example, if most of the > power is in bin X, there will also be some in bin X+1, X-1, and so on... > This I expect. What I don't understand is why when I plot the FFT of the > time-domain data from bins X and X+1, the tone appears at the same location > in the FFT output of both (X+1 has lower power). > > I hope this makes more sense :)Your starting point is obfuscated, at best. If you want to learn about DFTs, skip this 'property' alltogether. Rune
Reply by ●August 26, 20092009-08-26
>Your starting point is obfuscated, at best. If you want >to learn about DFTs, skip this 'property' alltogether. > >Rune >I believe I already have a reasonable understanding of DFTs... The whole point of my question is related to this property.
Reply by ●August 26, 20092009-08-26
On Wed, 26 Aug 2009 06:31:27 -0500, "jah" <andy.harriman@unb.ca> wrote:>Hi Guys, > >Thanks for your input. I realize my question may not make much sense :) >Let me try again... > >My end goal is to design an FFT-based channelizer (e.g. polyphase FFT, or >WOLA). Initially, I am starting with a simple FFT so that I can get a solid >understanding of what I am working with. > >I am trying to build from the following FFT property: > >"It converts a block of N time samples equally spaced in time into block >of N frequency samples equally spaced in frequency. For a continuous stream >of input time sample blocks, samples at a given point in successive output >blocks represent a translated, bandpass frequency signal or bin." >reference: http://www.pentek.com/tutorials/15_4/digdown.cfm > >My test: > >In Matlab, I am generating a pure tone of a particular frequency (not >centered perfectly on a bin), f1, of length, L, using my sample frequency, >fs. I then process the tone in a blockwise fashion (with no overlap between >blocks) using an N-point FFT. The result is a number of samples (L/N) for >each "bin". The spacing between bins is fs/N, and the sample rate per per >bin is fs/N. > >When I then plot my time-domain samples for each bin, what I am seeing is >that the tone appears in several adjacent bins. For example, if most of the >power is in bin X, there will also be some in bin X+1, X-1, and so on... >This I expect. What I don't understand is why when I plot the FFT of the >time-domain data from bins X and X+1, the tone appears at the same location >in the FFT output of both (X+1 has lower power). > >I hope this makes more sense :)Hi, I think I understand what you're looking at. If you can post your MATLAB code here, I'm pretty sure someone here will be able to explain exactly what you're seeing. jah, some time later, when you're feeling brave, have a look at: http://www.rfel.com/download/P04027%20-%20WSD0257_Slice_and_dice.pdf and http://www.sdrforum.org/pages/sdr05/2.1%20Comm%20Theory%201/2.1-04%20Lillington%20et%20al.pdf Good Luck, [-Rick-]
Reply by ●August 26, 20092009-08-26
>Hi, > I think I understand what you're looking at. >If you can post your MATLAB code here, I'm >pretty sure someone here will be able to >explain exactly what you're seeing. > >jah, some time later, when you're feeling brave, have >a look at: > >http://www.rfel.com/download/P04027%20-%20WSD0257_Slice_and_dice.pdf > >and > >http://www.sdrforum.org/pages/sdr05/2.1%20Comm%20Theory%201/2.1-04%20Lillington%20et%20al.pdf > >Good Luck, >[-Rick-]Hi Rick, Thank you. I have read both of the references you provided. The WOLA FFT is exactly where I am headed... eventually. For now though, I am trying to explore: "It is well known that a K-point FFT may be considered as a critically decimating filterbank, providing K equally spaced channels, all filtered by a K-point moving average filter response and decimated by a factor D = K." reference: http://www.sdrforum.org/pages/sdr05/2.1%20Comm%20Theory%201/2.1-04%20Lillington%20et%20al.pdf I have appended my Matlab code below. If you run it as is, you will see that the peak in channel 11 is at bin 2149. However if you look at channel 12, the peak is also in bin 2149! % This function implements an FFT-based channelization of a test signal % using an unwindowed FFT (rectangular). function fftChannelizerCompDSP() % Simulation parameters SAMPLE_FREQ = 102.4e6; % sample frequency (Hz) SAMPLE_PERIOD = 1/SAMPLE_FREQ; % sample period (s) CHANNEL_WIDTH = 200e3; NUM_SAMPLES = 2e6; % number of samples to process t = [SAMPLE_PERIOD:SAMPLE_PERIOD:SAMPLE_PERIOD*NUM_SAMPLES]; % simulation time SIG_FREQ = CHANNEL_WIDTH*10 + 10e3; % signal frequency (Hz) SIG_PHASE = 0; % signal phase (deg) SIG_AMPL = 0.995; % signal amplitude NOISE_AMPL = 1-SIG_AMPL; % noise amplitude % Generate a test signal noise = (((rand(NUM_SAMPLES,1)-0.5)*2)/(1/NOISE_AMPL))'; % random noise (uniform dist.) s1 = cos(2*pi*SIG_FREQ.*t + (SIG_PHASE*(pi/180))) + noise; % Plot the input data figure(1) subplot(211) plot(s1(1:1024)) title('Time-Domain Data') ylim([-1.1 1.1]) xlim([1 1024]) subplot(212) x=1:1024; y=20*log10(abs(fftshift(fft(s1(1:1024))/1024))); plot(x,y) title('Freq.-Domain Data') ylim([-100 10]) xlim([1 1024]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) % Calculate the FFT -> channelizedData(time,channel) fftLength = SAMPLE_FREQ/CHANNEL_WIDTH; % adjust the data length to be an integer multiple of the FFT length numFFTs = floor(length(s1)/fftLength); numSamples = numFFTs*fftLength; s1 = s1(1:numSamples); shiftSize = fftLength; % determine the number of channelized samples (how many samples per % channel) numChannelizedSamples = numSamples/shiftSize; % Determine the center bin (the nearest bin) centerBin = floor(SIG_FREQ/CHANNEL_WIDTH)+1; % pre-allocate variables (for speed) channelizedData = zeros(numChannelizedSamples, fftLength); % Display the parameters disp(['Mode: Unwindowed FFT (rectangular)']) disp(['Sample frequency (MHz): ' num2str(SAMPLE_FREQ/1e6)]) disp(['Channel width (kHz): ' num2str(CHANNEL_WIDTH/1e3)]) disp(['Signal frequency (MHz): ' num2str(SIG_FREQ/1e6)]) disp(['Center bin: ' num2str(centerBin)]) disp(['Number of channelized samples: ' num2str(numChannelizedSamples)]) % Perform the channelization j=1; for i=1:shiftSize:numSamples-fftLength, fftInputData = s1(i:i+(fftLength-1)); channelizedData(j,:) = fft(fftInputData)/fftLength; j=j+1; end % Plot the bin(s) (3 to either side of the main bin) figure(2) subplot(3,7,1) plot(real(channelizedData(:,centerBin-3))) title(['Real Data (Bin ' num2str(centerBin-3) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,2) plot(real(channelizedData(:,centerBin-2))) title(['Real Data (Bin ' num2str(centerBin-2) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,3) plot(real(channelizedData(:,centerBin-1))) title(['Real Data (Bin ' num2str(centerBin-1) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,4) plot(real(channelizedData(:,centerBin))) title(['Real Data (Bin ' num2str(centerBin) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,5) plot(real(channelizedData(:,centerBin+1))) title(['Real Data (Bin ' num2str(centerBin+1) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,6) plot(real(channelizedData(:,centerBin+2))) title(['Real Data (Bin ' num2str(centerBin+2) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,7) plot(real(channelizedData(:,centerBin+3))) title(['Real Data (Bin ' num2str(centerBin+3) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) % imaginary subplot(3,7,8) plot(imag(channelizedData(:,centerBin-3))) title(['Imag.l Data (Bin ' num2str(centerBin-3) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,9) plot(imag(channelizedData(:,centerBin-2))) title(['Imag.l Data (Bin ' num2str(centerBin-2) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,10) plot(imag(channelizedData(:,centerBin-1))) title(['Imag.l Data (Bin ' num2str(centerBin-1) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,11) plot(imag(channelizedData(:,centerBin))) title(['Imag.l Data (Bin ' num2str(centerBin) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,12) plot(imag(channelizedData(:,centerBin+1))) title(['Imag.l Data (Bin ' num2str(centerBin+1) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,13) plot(imag(channelizedData(:,centerBin+2))) title(['Imag.l Data (Bin ' num2str(centerBin+2) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) subplot(3,7,14) plot(imag(channelizedData(:,centerBin+3))) title(['Imag.l Data (Bin ' num2str(centerBin+3) ')']) ylim([-1.1 1.1]) xlim([1 numChannelizedSamples]) % FFT subplot(3,7,15) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin-3))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin-3) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) subplot(3,7,16) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin-2))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin-2) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) subplot(3,7,17) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin-1))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin-1) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) subplot(3,7,18) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) subplot(3,7,19) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin+1))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin+1) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) subplot(3,7,20) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin+2))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin+2) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) subplot(3,7,21) x=1:numChannelizedSamples; y=20*log10(abs(fftshift(fft(channelizedData(:,centerBin+3))/numChannelizedSamples))); plot(x,y) title(['Freq-Domain (Bin ' num2str(centerBin+3) ')']) ylim([-150 10]) xlim([1 numChannelizedSamples]) text(min(x(y==max(y))),max(y),[' \leftarrow Peak: ' num2str(max(y)) ' dB']) return
Reply by ●August 26, 20092009-08-26
On Aug 26, 7:36 am, "jah" <andy.harri...@unb.ca> wrote:> >Hi, >... > For now though, I am trying to explore: > > "It is well known that a K-point FFT may be considered as a critically > decimating filterbank, providing K equally spaced channels, all filtered by > a K-point moving average filter response and decimated by a factor D = K." > reference:http://www.sdrforum.org/pages/sdr05/2.1%20Comm%20Theory%201/2.1-04%20... > ...As you have set up your channelizer, the output channels are separated in frequency by the sample rate of your channel outputs. This makes the signal alias into adjacent channels at the same offset from center as in the maximum response channel. Dale B. Dalrymple
Reply by ●August 26, 20092009-08-26
jah <andy.harriman@unb.ca> wrote: < My end goal is to design an FFT-based channelizer (e.g. polyphase FFT, or < WOLA). Initially, I am starting with a simple FFT so that I can get a solid < understanding of what I am working with. < I am trying to build from the following FFT property: < "It converts a block of N time samples equally spaced in time into block < of N frequency samples equally spaced in frequency. For a continuous stream < of input time sample blocks, samples at a given point in successive output < blocks represent a translated, bandpass frequency signal or bin." < reference: http://www.pentek.com/tutorials/15_4/digdown.cfm You might read some of the other threads in this group, related to the boundary conditions and periodicity of the Fourier Transform. < In Matlab, I am generating a pure tone of a particular frequency (not < centered perfectly on a bin), f1, of length, L, using my sample frequency, < fs. I then process the tone in a blockwise fashion (with no overlap between < blocks) using an N-point FFT. The result is a number of samples (L/N) for < each "bin". The spacing between bins is fs/N, and the sample rate per per < bin is fs/N. I don't completely understand, so this might be the wrong suggestion. For the non-overlapping case, the DCT seems to be popular. That reduces the effects at block boundaries that you will see (hear) from the FFT. The DCT boundary condition is that the derivative is zero at the boundary. That reduces the discontinuity in the function value that you would otherwise see (hear). (Though that doesn't remove the spectral leakage question.) < When I then plot my time-domain samples for each bin, what I am seeing is < that the tone appears in several adjacent bins. For example, if most of the < power is in bin X, there will also be some in bin X+1, X-1, and so on... < This I expect. What I don't understand is why when I plot the FFT of the < time-domain data from bins X and X+1, the tone appears at the same location < in the FFT output of both (X+1 has lower power). The real answer is that the FFT has periodic boundary conditions, and the result you see is the result that you would see if you extended the block periodically in both directions, with period equal to the block length. As the block length increses, the result comes closer to the continuous transform result. (Or the bins become closer together, if you like to see it that way.) -- glen






