MATLAB MATLAB: Find Peaks in Frequency & Amplitude

  • Thread starter Thread starter Ophyron
  • Start date Start date
  • Tags Tags
    Matlab
Click For Summary
SUMMARY

This discussion focuses on using MATLAB to identify peaks in frequency and amplitude from FFT results of .wav files. The user, Nick, seeks to find frequencies with peaks above 20 dB within the first 5000 Hz. Key solutions include using logical indexing to isolate peaks and employing the findpeaks function to label these peaks effectively. The discussion emphasizes the importance of unwrapping the FFT with fftshift before applying peak detection techniques.

PREREQUISITES
  • Familiarity with MATLAB programming environment
  • Understanding of Fast Fourier Transform (FFT) and its application in signal processing
  • Knowledge of logical indexing in MATLAB
  • Experience with the findpeaks function in MATLAB
NEXT STEPS
  • Learn how to use fftshift to rearrange FFT output for better peak detection
  • Explore the findpeaks function in MATLAB for advanced peak analysis
  • Research logical indexing techniques in MATLAB for efficient data manipulation
  • Investigate methods to set thresholds for peak detection in frequency analysis
USEFUL FOR

Signal processing engineers, MATLAB users analyzing audio data, and researchers interested in frequency analysis and peak detection techniques.

Ophyron
Messages
1
Reaction score
0
hi,

i'm pretty new to MATLAB - but I've been using it to perform FFT's on .wav files to graph frequency and amplitude. I've been using the following code to generate the graphs:
Matlab:
[h,Fs] = wavread('x.wav');

H = fft(h);
N = length(h);
f = (0:(N-1))*(Fs/N);
t = (0:(N-1))/Fs;

figure(1);

clf;
plot(f,20*log10(abs(H)));

grid;

xlabel('Frequency (Hz)');
ylabel('Amplitude (dB)');

is there any way i can find the frequency at which peaks appear, and the amplitude of these peaks with code? I'm only really interested in the peaks in the first 5000Hz or so, above about 20dB. anyone got any ideas? any pointers would be much appreciated! thanks

take care

Nick
 
Last edited by a moderator:
Physics news on Phys.org
When you say peaks, do you mean the events in time that are the loudest or the places on a FFT plotted frequency spectrum where certain frequency have higher incidences.

In the case of the second example, you could programmatically walk through the array of frequencies and list only those above the 20db mark and zero the others so that they show up more clearly in your plot.

Here's more on using the FFT function:

https://www.mathworks.com/help/matlab/ref/fft.html?searchHighlight=fft&s_tid=doc_srchtitle
 
This may not be a complete specification of what you mean by "peak", but you can write a vector statement that picks out points that are greater than their immediate neighbors to either side.

First of all, your H is complex. You probably want the amplitude X = abs(H);

OK, now there's a really useful trick in Matlab called logical indexing. If you have a vector I of 1's and 0's the same length as X, then X(I) will pick out the elements corresponding to the 1's. Of course, you probably want the locations of those elements for your question. find(I) will do that.

OK, so now I'm going to build a statement which will generate such a vector of 1's and 0's. I'll append the value ##+\infty## to each end of X so that the peaks don't occur there. The expression X > [X(2:end),inf] compares each element of X to the element to its immediate right. The insertion of inf is to pad out the second vector to the right length, and choosing the value ##\infty## as I said guarantees that the comparison will fail at the endpoint.

Finally, I'll use element-wise AND (a single ampersand) to combine this comparison with the one in the other direction. Thus, the whole statement is this:

Peaks = find( (X > [X(2:end), inf]) & (X > [inf, X(1:end-1)] );

As I said, you might decide you need to add other criteria to define your peaks, also connected with "&".

Disclaimer: I don't have Matlab on this computer to test that I got all the syntax right.
 
Last edited:
  • Like
Likes jedishrfu
The command find(max()) will return the indices of the max of an array.
 
First you need to unwrap your fft with fftshift. Then you can use the findpeaks command to find and label peaks. You can then compare to a threshold that you set so as to ignore small peaks.
 
Check out the findpeaks command here.
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 9 ·
Replies
9
Views
5K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 3 ·
Replies
3
Views
8K
  • · Replies 1 ·
Replies
1
Views
10K