Help - Search - Members - Calendar
Full Version: Matlab sound Analysis
Hydrogenaudio Forums > Hydrogenaudio Forum > General Audio
inadaze
Hi,
I need some generous person to help me! I am having problems figuring out how to analyze my recorded sounds in Matlab. I would like to plot a stem graph where my x-axis is the frequencies present in the sound and my y-axis to be the magnitude of these frequencies in dB.
If there is some one out there with a heart of gold who could help, please do...
Everything that I have tried has given me one or neither of what I need.

Thanks
Jay
SebastianG
i'm not 100% sure right now (i've currently no version of matlab installed) but AFAIK you'll able to find examples if you run the matlab modules demo by typing:
> demo
(or something similar)

> help freqz
> help plot
might also help.

bye,
Sebastian
Gecko
Try this: http://www.cs.tut.fi/sgn/arg/intro/basics.html
inadaze
Thanks for the help!!
I have a question though. in the example of the piano note at:
http://www.cs.tut.fi/sgn/arg/intro/basics.html
they use the specgram function. I have looked at this before but I cannot understand what the NFFT parameter is? Is it the amount of sample used to define the amplitude of something?

I have also used the spectrum function with some success, but I find that the results are not very accurate. I have created a sin wave at 440Hz and when I analyze it, the graph plot is close but sometimes it is almost 50- 100 Hz off. Does anyone know if its something I am doing or maybe the sin wave tone is only approx. 440Hz when I create it?

Just a little confused,
Thanks
Jay
Gecko
QUOTE(inadaze @ Jun 17 2004, 05:51 PM)
they use the specgram function.  I have looked at this before but I cannot understand what the NFFT parameter is?

I believe it is the window size the fft is performed on. When you want to plot frequency graphs over time, you only want to analyze a small portion of samples at a time. NFFT is probably the size of this window. It is a tradeoff between time precision and frequency precision. Small numbers mean high time resolution while high numbers mean high frequency resolution.

It's a good idea to use powers of two because of the way the fast discrete fourier transform works.

QUOTE
I have also used the spectrum function with some success, but I find that the results are not very accurate.  I have created a sin wave at 440Hz and when I analyze it, the graph plot is close but sometimes it is almost 50- 100 Hz off.  Does anyone know if its something I am doing or maybe the sin wave tone is only approx. 440Hz when I create it?


Maybe the window is too short?

With NFFT = 256 you look at 256 samples at a time. If the data is sampled at 44100 samples/second that would be ca 0.0058 seconds of sound. So the lowest frequency you can discriminate is ca. 172Hz (1/0.0058). edit: The discrete frequencies you will see are multiples of that base frequency. 172.27, 344.53, 516.80, 689.06. As you can see the frequency resolution isn't good enough.

Old text: The next frequency bin would be at 344Hz, the next at 689Hz.

Someone please verify this! It's been a while.
inadaze
QUOTE(Gecko @ Jun 17 2004, 11:52 AM)
QUOTE(inadaze @ Jun 17 2004, 05:51 PM)
they use the specgram function.  I have looked at this before but I cannot understand what the NFFT parameter is?

I believe it is the window size the fft is performed on. When you want to plot frequency graphs over time, you only want to analyze a small portion of samples at a time. NFFT is probably the size of this window. It is a tradeoff between time precision and frequency precision. Small numbers mean high time resolution while high numbers mean high frequency resolution.

It's a good idea to use powers of two because of the way the fast discrete fourier transform works.

QUOTE
I have also used the spectrum function with some success, but I find that the results are not very accurate.  I have created a sin wave at 440Hz and when I analyze it, the graph plot is close but sometimes it is almost 50- 100 Hz off.  Does anyone know if its something I am doing or maybe the sin wave tone is only approx. 440Hz when I create it?


Maybe the window is too short?

With NFFT = 256 you look at 256 samples at a time. If the data is sampled at 44100 samples/second that would be ca 0.0058 seconds of sound. So the lowest frequency you can discriminate is ca. 172Hz (1/0.0058). edit: The discrete frequencies you will see are multiples of that base frequency. 172.27, 344.53, 516.80, 689.06. As you can see the frequency resolution isn't good enough.

Old text: The next frequency bin would be at 344Hz, the next at 689Hz.

Someone please verify this! It's been a while.

Hey,
IF you look here:
http://www.ele.uri.edu/~hansenj/projects/ele436/fft.pdf
it does explain a little to me, but I still don't understand 100%.

would resampling the data at a lower sample frequency help? I am really very lost....sigh...

all I am trying to do is find the dominant audio frequencies in a sound. It seems that this is a lot more difficult than it should be. Isn't there some easier way?

Sigh...
Jay
2Bdecided
You can be accurate in time, or accurate in frequency, but not both. That's not a limit of MATLAB - it's a fundamental theoretical limit. You need to "look at" lots of cycles of the wave to determine the frequency exactly.

So, short window=accurate in time, but coarse frequency resolution
Long window=accurate in frequency, but coarse time resolution


Try longer FFT lengths to get better spectral (frequency) accuracy.

1024 is a good number.

Remember, human frequency and loudness perception is logarithmic - the MATLAB plots aren't.

Cheers,
David.
inadaze
Thanks for your reply,
I'll try what you suggest. Time is not important (if I must give one up for the other), but I would like to know the amplitude of each frequency(even if it is just by comparing it to the other frequencies present in the sound.). How can this be done?

Also, why is it that one cannot be accurate in both freq. and time?

And when you say that freq. and loudness is logarithmic and Matlab plots are not: Do you mean that I would have to scale the plots logarithmically and not use the default setting?

Thanks
Jay
2Bdecided
QUOTE(inadaze @ Jun 18 2004, 01:25 PM)
Thanks for your reply,
I'll try what you suggest.  Time is not important (if I must give one up for the other), but I would like to know the amplitude of each frequency(even if it is just by comparing it to the other frequencies present in the sound.).  How can this be done?

Just use an FFT, or one of the routines you've already been pointed to.

You know you can look at the source code for most MATLAB functions, and see exactly what they're doing? That should help. If not, see below...


QUOTE
Also, why is it that one cannot be accurate in both freq. and time?


I already answered that wink.gif because in a very short time, you simply don't have enough information on frequency. At the extreme, in a single sample, you don't have any frequency information at all.


QUOTE
And when you say that freq. and loudness is logarithmic and Matlab plots are not: Do you mean that I would have to scale the plots logarithmically and not use the default setting?


IME (with an _old_ version of MATLAB) you can't plot spectrograms with a log frequency scale in MATLAB automatically. log amplitude is easy though - just 20*log10 the data. It's not essential, but it might help you to see what's in the audio file.

If you have your mono audio in an array called my_tone, then try this:

CODE

window_length=4096;
freq_my_tone=fft(my_tone(1:window_length).*hanning(window_length));
frequency_scale=(1:window_length/2)*fs/window_length;
semilogx(frequency_scale,20*log10(abs(freq_my_tone(1:window_length/2))))
axis([20 20000 -20 80])
xlabel('frequency / Hz')
ylabel('amplitude / dB')


(for stereo audio, just select one channel in the second line, replacing my_tone(1:window_length) with my_tone(1,1:window_length) or mytone(1:window_length,1) depending on which way you've loaded data into the array).


The one thing that's missing from this is any calibration of the amplitude scale. For a given window length and window function, you have to take a full scale sine wave (I use +/-1 range with MATLAB, as do the built-in wav functions), pass it through the above function, note the peak amplitude, and then subtract this from all subsequent plots to get figures relative to 0dB FS. This correction factor will change if you change the window function or window length. You'll have to change the axis statement as appropriate.

Hope this helps.

Cheers,
David.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.