MATLAB: Find Peaks in Frequency & Amplitude

  • Context: MATLAB 
  • Thread starter Thread starter Ophyron
  • Start date Start date
  • Tags Tags
    Matlab
Click For Summary

Discussion Overview

The discussion revolves around using MATLAB to identify peaks in frequency and amplitude from FFT results of .wav files. Participants explore various methods and functions within MATLAB to achieve this, focusing on the first 5000 Hz and amplitudes above 20 dB.

Discussion Character

  • Technical explanation
  • Exploratory
  • Mathematical reasoning

Main Points Raised

  • One participant seeks assistance in finding the frequency and amplitude of peaks in their FFT graph, specifically above 20 dB and within 5000 Hz.
  • Another participant clarifies the definition of "peaks," suggesting it could refer to either loudest events in time or higher incidences in the FFT spectrum.
  • A suggestion is made to programmatically filter the FFT results to only display frequencies above 20 dB for clarity in the plot.
  • A method is proposed involving logical indexing to identify peaks by comparing each amplitude value to its neighbors, with a specific code snippet provided for implementation.
  • Another participant mentions using the command find(max()) to locate the indices of maximum values in an array.
  • A suggestion is made to use fftshift to unwrap the FFT results before applying the findpeaks command, which can help in identifying and labeling peaks while allowing for threshold comparisons.
  • Reference to the findpeaks command is provided for further exploration.

Areas of Agreement / Disagreement

Participants present multiple methods and approaches for identifying peaks, with no consensus on a single solution. Various techniques are discussed, indicating a range of opinions on the best approach.

Contextual Notes

Some methods rely on specific assumptions about peak definitions and may require additional criteria for peak identification. The discussion does not resolve the best practices for peak detection in this context.

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   Reactions: 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
3K
  • · 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
10K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 3 ·
Replies
3
Views
8K