Why does my FFT return all zeros for certain sound files?

38 views (last 30 days)
Hi!
I've been working on a Equaliser and I want it to display a frequency-domain graph from an audio file that is read. I had it working, at least so I thought, so I was experimenting with all the sound files I could find. (The application allows .wav, .flac, .m4a and .mp3 files).
For almost all of the files I have tried the code (shown below) works, as seen in this picture.
Then this is the ouput I get with one of two .mp3 files. The matlab code plays the file, and it clearly reads it correctly due to the top display showing the waveform.
Below is the code that I am using:
file = app.SelectFileDropDown.Value;
[y,Fs] = audioread(file);
n = length(y);
t = 0:seconds(1/Fs):seconds(n/Fs);
t = t(1:end-1);
plot(app.VisualiserDisplay,t, y); % This displays the waveform at the top
N = 2^12;
j = 0:N-1;
f = (Fs/N).*j;
X = fft(y,N); % This is _supposed_ to display the graph at the bottom
semilogx(app.EqualiserDisplay, f(1:round(20000/(Fs/N))),20*log(abs(X(1:round(20000/(Fs/N))))));
I was playing around to try and determine why it wasn't working and discovered that for the files that don't work the 'double' X is filled with all zeros but y is not! For the working files, X is filled with complex numbers, as it should be. Can anyone suggest why this might be happening? It seems rather random that some files return all zeros and others work as intended?
Thanks in advance!
  2 Comments
Mathieu NOE
Mathieu NOE on 24 Mar 2021
hello
can you share one of your audio file that causes trouble ?
LJC
LJC on 24 Mar 2021
Can do! I did try to attach them to the original post but unfortunately I can't add .mp3s. Here is one in a .zip!

Sign in to comment.

Accepted Answer

Mathieu NOE
Mathieu NOE on 24 Mar 2021
Luke - see above
again :
I found where the issue is on the OP code -
N = 2^12;
j = 0:N-1;
f = (Fs/N).*j;
X = fft(y,N); % This is _supposed_ to display the graph at the bottom
the issue is that this is not an averaged fft for the entire signal duration !!
this takes only the first N samples of data and display the fft of that single data buffer
read the fft help :
% FFT(X,N) is the N-point FFT,
% padded with zeros if X has less than N points and truncated if it has more.
in the case of that specific audio file , the first N samples are zero (indeed the first 10,000 samples are zero) , so the fft = 0 all the same.
if one would do an averaged fft for the entire signal , this is my home made fft function :
function [freq_vector,fft_spectrum] = myfft_peak(signal, Fs, nfft, Overlap)
% FFT peak spectrum of signal (example sinus amplitude 1 = 0 dB after fft).
% Linear averaging
% signal - input signal,
% Fs - Sampling frequency (Hz).
% nfft - FFT window size
% Overlap - buffer percentage of overlap % (between 0 and 0.95)
signal = signal(:);
samples = length(signal);
% fill signal with zeros if its length is lower than nfft
if samples<nfft
s_tmp = zeros(nfft,1);
s_tmp((1:samples)) = signal;
signal = s_tmp;
samples = nfft;
end
% window : hanning
window = hanning(nfft);
window = window(:);
% compute fft with overlap
offset = fix((1-Overlap)*nfft);
spectnum = 1+ fix((samples-nfft)/offset); % Number of windows
% % for info is equivalent to :
% noverlap = Overlap*nfft;
% spectnum = fix((samples-noverlap)/(nfft-noverlap)); % Number of windows
% main loop
fft_spectrum = 0;
for i=1:spectnum
start = (i-1)*offset;
sw = signal((1+start):(start+nfft)).*window;
fft_spectrum = fft_spectrum + (abs(fft(sw))*4/nfft); % X=fft(x.*hanning(N))*4/N; % hanning only
end
fft_spectrum = fft_spectrum/spectnum; % to do linear averaging scaling
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
fft_spectrum = fft_spectrum(select);
freq_vector = (select - 1)*Fs/nfft;
end
  4 Comments
LJC
LJC on 24 Mar 2021
This updated version works perfectly! Thank you so much!

Sign in to comment.

More Answers (0)

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!