Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Matlab sound Analysis (Read 4426 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Matlab sound Analysis

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

Matlab sound Analysis

Reply #1
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


Matlab sound Analysis

Reply #3
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

Matlab sound Analysis

Reply #4
Quote
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). [span style='font-size:8pt;line-height:100%']edit:[/span] 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.

[span style='font-size:8pt;line-height:100%']Old text: The next frequency bin would be at 344Hz, the next at 689Hz.[/span]

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

Matlab sound Analysis

Reply #5
Quote
Quote
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). [span style='font-size:8pt;line-height:100%']edit:[/span] 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.

[span style='font-size:8pt;line-height:100%']Old text: The next frequency bin would be at 344Hz, the next at 689Hz.[/span]

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

Matlab sound Analysis

Reply #6
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.

Matlab sound Analysis

Reply #7
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

 

Matlab sound Analysis

Reply #8
Quote
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  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: [Select]
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.