user2482542
user2482542

Reputation: 361

Finding peaks within a specified range in matlab

I'm trying to analyze an audio file so I generated the FFT of the signal and found the peaks above a certain threshold. This is a part of the code:

%---------------------------Performing FFT--------------------------------%
 for i = 2:No_of_peaks

    song_seg = song(max_col(i-1):max_col(i)-1);
%     song_seg = song(max_col(6):max_col(7)-1);
    L = length(song_seg);    
    NFFT = 2^nextpow2(L); % Next power of 2 from length of y

    seg_fft = fft(song_seg,NFFT);%/L;

    N=5;Fst1=50;Fp1=60; Fp2=1040; Fst2=1050;

%     d = fdesign.bandpass('N,Fst1,Fp1,Fp2,Fst2');
%     h = design(d);
%     seg_fft = filter(h, seg_fft);

%     seg_fft(1) = 0;
%     
    f = FS/2*linspace(0,1,NFFT/2+1);
    seg_fft2 = 2*abs(seg_fft(1:NFFT/2+1));
    L5 = length(song_seg);

    figure(1+i)
    plot(f,seg_fft2)
    title('Frequency spectrum of signal')
    xlabel('Frequency (Hz)')
    %xlim([0 2500])
    ylabel('|Y(f)|')
    ylim([0 300])

    [points, loc] = findpeaks(seg_fft2,'MINPEAKHEIGHT',20)
 end

Now that I have the points and loc i want to be able to extract the peaks that are between 60Hz and 1000Hz. How can i write a code to implement it and store the peak amplitudes as well as the corresponding frequency values???

Thanx in advance

Upvotes: 0

Views: 2061

Answers (2)

Buck Thorn
Buck Thorn

Reputation: 5073

Two similar ways of going about this. First, after you FFT, pick the subset of the spectrum containing the region of interest and apply the peak search routine only to that section:

 for i = 2:No_of_peaks

    % ... code steps where you fft etc here ...
    % ... now pick the region of interest

    fmin = 60;
    fmax = 1000;
    region_of_interest = fmax>f & f>fmin;
    froi = f(region_of_interest);  

    [points, loc] = findpeaks(seg_fft2(region_of_interest),'MINPEAKHEIGHT',20)

    % index into froi to find the frequency of the peaks
    fpeaks = froi(loc);

 end

A very similar alternative is to pick peaks, then pick the subset within the frequency region of interest, like so:

 for i = 2:No_of_peaks

    % lots of code here to fft etc ...

    [points, loc] = findpeaks(seg_fft2,'MINPEAKHEIGHT',20)

    % find the peaks within the region of interest 

    fmin = 60;
    fmax = 1000;
    peaks_of_interest = find(fmax>f(loc) & f(loc)>fmin);
    fpeaks = f(loc(peaks_of_interest));
    apeaks = points(loc(peaks_of_interest));  % magnitude of the peaks


 end

Upvotes: 2

You can use:

PeakFinder

Another easier method is to make the first derivative of your function (use a diff vector with your discrete frequencies) and then locate the peaks. The amplitudes can be taken from your original signal.

Upvotes: 2

Related Questions