Harmonic product spectrum Matlab coding error - matlab

I'm trying to find the fundamental frequencies present in a piano recording using MATLAB. These are the steps I've followed;
Find the envelop of the signal
Find the note onsets
perform FFT between each onset
Harmonic product spectrum.
It's when I try to implement the HPS algorithm that I face a "dimensions don't agree" error. This is the whole code that I've used.
[song,FS] = wavread('C major.wav');
%sound(song,FS);
P = 20000;
N=length(song); % length of song
t=0:1/FS:(N-1)/FS; % define time period
song = sum(song,2);
song=abs(song);
% Plot time domain signal
figure(1);
subplot(2,1,1)
plot(t,3*song)
title('Wave File')
ylabel('Amplitude')
xlabel('Length (in seconds)')
%ylim([-1.1 1.1])
xlim([0 N/FS])
%----------------------Finding the envelope of the signal-----------------%
% Gaussian Filter
x = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -x .* exp( -(x.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
% Plot Gaussian Filter
subplot(2,1,2)
plot(myFilter)
title('Edge Detection Filter')
% fft convolution
myFilter = myFilter(:); % create a column vector
song(length(song)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(song)) = 0; %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));
tedges=edges(P:N+P-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize
%---------------------------Onset Detection-------------------------------%
% Finding peaks
maxtab = [];
mintab = [];
x = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN;
max_pos = NaN;
lookformax = 1;
for i=1:length(tedges)
peak = tedges(i:i);
if peak > max1,
max1 = peak;
max_pos = x(i);
end
if peak < min1,
min1 = peak;
min_pos = x(i);
end
if lookformax
if peak < max1-0.001
maxtab = [maxtab ; max_pos max1];
min1 = peak;
min_pos = x(i);
lookformax = 0;
end
else
if peak > min1+0.005
mintab = [mintab ; min_pos min1];
max1 = peak;
max_pos = x(i);
lookformax = 1;
end
end
end
% % Plot song filtered with edge detector
figure(2)
plot(1/FS:1/FS:N/FS,tedges)
title('Song Filtered With Edge Detector 1')
xlabel('Time (s)')
ylabel('Amplitude')
ylim([-1 1.1])
xlim([0 N/FS])
hold on;
plot(maxtab(:,1)/FS, maxtab(:,2), 'ro')
plot(mintab(:,1)/FS, mintab(:,2), 'ko')
max_col = maxtab(:,1);
peaks_det = max_col/FS;
No_of_peaks = length(peaks_det);
[song,FS] = wavread('C major.wav');
%---------------------------Performing STFT--------------------------------%
h = 1;
for i = 2:No_of_peaks
song_seg = song(max_col(i-1):max_col(i)-1);
L = length(song_seg);
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
seg_fft = fft(song_seg,NFFT);%/L;
U = size(seg_fft,1)
% In harmonic prodcut spectrum, you downsample the fft data several times and multiply all those with the original fft data to get the maximum peak.
%HPS
seg_fft = seg_fft(1 : size(seg_fft,1)/2 );
seg_fft = abs(seg_fft);
%HPS: downsampling
for i = 1:length(seg_fft)
seg_fft2(i,1) = 1;
seg_fft3(i,1) = 1;
seg_fft4(i,1) = 1;
% seg_fft5(i,1) = 1;
end
for i = 1:floor((length(seg_fft)-1)/2)
seg_fft2(i,1) = (seg_fft(2*i,1) + seg_fft((2*i)+1,1))/2;
end
for i = 1:floor((length(seg_fft)-2)/3)
seg_fft3(i,1) = (seg_fft(3*i,1) + seg_fft((3*i)+1,1) + seg_fft((3*i)+2,1))/3;
end
for i = 1:floor((length(seg_fft)-3)/4)
seg_fft4(i,1) = (seg_fft(4*i,1) + seg_fft((4*i)+1,1) + seg_fft((4*i)+2,1) + seg_fft((4*i)+3,1))/4;
end
%HPS, PartII: calculate product
p1 = (seg_fft3) .* (seg_fft4);
p2 = p1.* (seg_fft2);
p3 = p2.* (seg_fft);
HPS, PartIII: find max
[f_y1,I] = max(p3)
for c = 1 : length(p3)
if(p3(c,1) == f_y1)
index = c;
end
end
% Convert that to a frequency
f_y(h) = (index / NFFT) * FS;
h=h+1;
f_y = abs(f_y)';
end
Before implementing p3 = p2.* (seg_fft); the sizes of seg_fft, seg_fft2, seg_fft3, seg_fft4 all have the same dimensions of 16384 1. Then when I DO implement p3 = p2.* (seg_fft); the size of seg_fft changes to 8192 1 while the sizes of rest remain at 16384 1 thus causing an error in multiplication as the dimensions aren't the same.
I'm really confused as to why this keeps happening and nothing I try seems to work out. Would really REALLY appreciate some help here... If someone could fix this code it'd be a GREAT help... Thanx in advance.. I'm real desperate here......

Related

Get Velocity from Acceleration data(10 Hz), using "cumsum" or Omega Arithmetic Method

I want to get Velocity from Acceleration data(10 Hz) in MATLAB. I have the real Constant Velocity that I've calculated by (DeltaX/DeltaT). The problem is that when I use the code below, the graph has lot's of differences with the Real Velocity Graph. I've used both cumsum and omega arithmetic, could someone tell me if there is any problem in my codes of any of both methods? Thank you in advance.
link to access txt files: https://spaces.hightail.com/space/19rl7
%%%%%%%%%%%%%%% cumsum METHOD %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fid1 = fopen( 'Acceleration_data.txt', 'r' );
fid2 = fopen( 'Actual_Velocity_data.txt', 'r' );
formatSpec = '%f';
vel_Fast_Running = fscanf(fid2,formatSpec);
acc_Fast_Running = fscanf(fid1,formatSpec);
Fs=1000;
Ns = 10;%% Sampling freq
T = 1/Fs; %% Period
L = length(acc_Fast_Running); %% signal length
acceleration_data=acc_Fast_Running-median(acc_Fast_Running);
[B,A] = butter(6,0.098,'high'); %% highpass filter
a_filtr = filtfilt(B,A,acc_Fast_Running); %% acceleratiof w/o DC
v_cumsum = cumsum(a_filtr)*0.1;%integration
v_cumsum = v_cumsum - mean(v_cumsum);
[B,A] = butter(3,0.12,'low');
v_cumsum_filtr = filtfilt(B,A,v_cumsum);
%subplot(1,2,2);plot([v_cumsum' v_cumsum_filtr']);
hold on;plot(vel_Fast_Running)
plot(v_cumsum_filtr)
legend('Actual Vel','Vel From integration')
xlabel('Time')
ylabel('Velocity m/s')
%%%%%%%%%%%%%%% OMEGA ARITHMETIC METHOD %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fid1 = fopen( 'Acceleration_data.txt', 'r' );
fid2 = fopen( 'Actual_Velocity_data.txt', 'r' );
formatSpec = '%f';
vel_Fast_Running = fscanf(fid2,formatSpec);
acc_Fast_Running = fscanf(fid1,formatSpec);
Fs=1000;
Ns = 10;%% Sampling freq
T = 1/Fs; %% Period
L = length(acc_Fast_Running ); %% signal length
%t=(1:L)/Fs;
f = Fs*(0:L-1)/L;
acc_Fast_Running =acc_Fast_Running -mean(acc_Fast_Running );
[B,A] = butter(6,0.098,'high'); %% highpass filter
a_filtr = filtfilt(B,A,acc_Fast_Running);
Y = (fft(a_filtr)); % Fast fourier Transform
for i = 1 : L
if f(i) ~= 0 && f(i) < Fs/2;
Yf(i) = Y(i)/(2*pi*f(i)*sqrt(-1)) ;
else
Yf(i) = 0;
end
end
Yf(1:100)=0; %%
d_oa = real(ifft(Yf));
d1 = designfilt('lowpassiir','FilterOrder',4, ...
'HalfPowerFrequency',0.1,'DesignMethod','butter');
y = filtfilt(d1,d_oa);
figure(15)
%plot( d_oa)
subplot(2,1,1)
plot(y)
xlabel('Time')
ylabel('Vel be Omega Method')
subplot(2,1,2)
plot(vel_Fast_Running )
xlabel('Time')
ylabel('Actual Velocity m/s')

Plotting Harmonic Product Spectrum using MATLAB

I used Harmonic Product Spectrum to find the fundamental note present when a number of harmonics are present. This is the code I've implemented;
[song,FS] = wavread('C major.wav');
%sound(song,FS);
P = 20000;
N=length(song); % length of song
t=0:1/FS:(N-1)/FS; % define time period
song = sum(song,2);
song=abs(song);
%----------------------Finding the envelope of the signal-----------------%
% Gaussian Filter
w = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -w .* exp( -(w.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
% fft convolution
myFilter = myFilter(:); % create a column vector
song(length(song)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(song)) = 0; %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));
tedges=edges(P:N+P-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize
%---------------------------Onset Detection-------------------------------%
% Finding peaks
maxtab = [];
mintab = [];
x = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN;
max_pos = NaN;
lookformax = 1;
for i=1:length(tedges)
peak = tedges(i:i);
if peak > max1,
max1 = peak;
max_pos = x(i);
end
if peak < min1,
min1 = peak;
min_pos = x(i);
end
if lookformax
if peak < max1-0.07
maxtab = [maxtab ; max_pos max1];
min1 = peak;
min_pos = x(i);
lookformax = 0;
end
else
if peak > min1+0.08
mintab = [mintab ; min_pos min1];
max1 = peak;
max_pos = x(i);
lookformax = 1;
end
end
end
max_col = maxtab(:,1);
peaks_det = max_col/FS;
No_of_peaks = length(peaks_det);
[song,FS] = wavread('C major.wav');
song = sum(song,2);
%---------------------------Performing STFT--------------------------------%
h = 1;
%for i = 2:No_of_peaks
song_seg = song(max_col(7-1):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;
f = FS/2*linspace(0,1,NFFT/2+1);
seg_fft_2 = 2*abs(seg_fft(1:NFFT/2+1));
L5 = length(song_seg);
figure(6)
plot(f,seg_fft_2)
%plot(1:L/2,seg_fft(1:L/2))
title('Frequency spectrum of signal (seg_fft)')
xlabel('Frequency (Hz)')
xlim([0 2500])
ylabel('|Y(f)|')
ylim([0 500])
%----------------Performing Harmonic Product Spectrum---------------------%
% In harmonic prodcut spectrum, you downsample the fft data several times and multiply all those with the original fft data to get the maximum peak.
%HPS
seg_fft = seg_fft(1 : size(seg_fft,1)/2 );
seg_fft = abs(seg_fft);
a = length(seg_fft);
seg_fft2 = ones(size(seg_fft));
seg_fft3 = ones(size(seg_fft));
seg_fft4 = ones(size(seg_fft));
seg_fft5 = ones(size(seg_fft));
for i = 1:((length(seg_fft)-1)/2)
seg_fft2(i,1) = seg_fft(2*i,1);%(seg_fft(2*i,1) + seg_fft((2*i)+1,1))/2;
end
%b= size(seg_fft2)
L1 = length(seg_fft2);
NFFT1 = 2^nextpow2(L1); % Next power of 2 from length of y
f1 = FS/2*linspace(0,1,NFFT1/2+1);
seg_fft12 = 2*abs(seg_fft2(1:NFFT1/2+1));
figure(7);
plot(f1,seg_fft12)
title('Frequency spectrum of signal (seg_fft2)')
xlabel('Frequency (Hz)')
xlim([0 2500])
ylabel('|Y(f)|')
ylim([0 500])
This is the plot for Figure 6
So in the real scenario once I perform HPS (downsample by 2) the peak at 440.1 should shift down to 220 while the peak at 881 should shift down to around 440. But when I plot the graph that is not what I get. Insetad this is the graph I get,
Why don't I get the correct graph???? I don't seem to understand what Im doing wrong here... Can someone please have a look and let me know.. Thank you.....
The problem with your downsampling is that you trim the vector by 2x before doing the downsampling, instead of after. You do
seg_fft = seg_fft(1 : size(seg_fft,1)/2 );
% [... other stuff ...]
for i = 1:((length(seg_fft)-1)/2)
seg_fft2(i,1) = seg_fft(2*i,1);%(seg_fft(2*i,1) + seg_fft((2*i)+1,1))/2;
end
Instead you need to downsample first, then trim:
for i = 1:((length(seg_fft)-1)/2)
seg_fft2(i,1) = seg_fft(2*i,1);%(seg_fft(2*i,1) + seg_fft((2*i)+1,1))/2;
end
seg_fft = seg_fft(1 : size(seg_fft,1)/2 );
UPDATE you asked why this does not preserve the peaks. The short answer is that you may not be "looking at" the peaks. If you want to keep (nearest) peaks during downsampling by n, you can do the following:
n = 3; % degree of decimation or downsampling we want to do
N = size(seg_fft, 1); % number of samples in original FFT
Nn = n * floor(N/n); % number of samples that can be divided by n
fftBlock = reshape(seg_fft(1:Nn, 1), n, N);
fftResampled = max(fftBlock);
How does this work? Let's use a simple example of 10 x 1 points:
seg_fft = [0 1 10 5 4 3 6 12 4 3];
We want "every 3rd". Naive algorithm would give
fftResampled = [2 3 7];
But we would have liked the "peaks" [10 3 12] - unfortunately they are not in the right location.
After reshaping the array (and losing the last element; if it might be an interesting value we could append and pad with zeros) we get:
fftBlock = [0 5 6;
1 4 3;
10 3 4];
(Remember that Matlab matrices are rows-first)
Now taking the max (the function will operate along the first dimension unless we tell it otherwise) you get
fftResampled = [10 5 6];
i.e. always the peak. While this preserves the peaks, it does mean that your "valleys" are getting filled in a bit.
Bottom line: there is no way not to destroy "some" information in the process of downsampling - you are, after all, throwing half the samples away. What you keep, and how you account for the information content in the data you discard, is something only you can decide, as it will depend on your application, and what is important for you.

Wrong onset detection when using MATLAB GUI

I'm trying to create a GUI on MATLAB that will automatically transcribe piano music when a .wav file is given as an input. Before using GUI I created the whole algorithm using MATLAB and it worked just fine.
Now when I create the GUI and transfer the codings there, my onset (peak) detection produces wrong results as the envelope of my signal is not as smooth as how it was when run using matlab script.
As you can see the envelope is pretty much smooth when used normally rather than when using GUI. Due to these peaks are detected all over the slope as well and not just at the actal peaks.
This is the code I used to build the algorithm:
[song,FS] = wavread('C major.wav');
P = 20000;
N=length(song); % length of song
t=0:1/FS:(N-1)/FS; % define time period
song = sum(song,2);
song=abs(song);
%----------------------Finding the envelope of the signal-----------------%
% Gaussian Filter
w = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -w .* exp( -(w.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
% fft convolution
myFilter = myFilter(:); % create a column vector
song(length(song)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(song)) = 0; %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));
tedges=edges(P:N+P-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize
%---------------------------Onset Detection-------------------------------%
% Finding peaks
maxtab = [];
mintab = [];
j = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN;
max_pos = NaN;
lookformax = 1;
for i=1:length(tedges)
peak = tedges(i:i);
if peak > max1,
max1 = peak;
max_pos = j(i);
end
if peak < min1,
min1 = peak;
min_pos = j(i);
end
if lookformax
if peak < max1-0.09
maxtab = [maxtab ; max_pos max1];
min1 = peak;
min_pos = j(i);
lookformax = 0;
end
else
if peak > min1+0.08
mintab = [mintab ; min_pos min1];
max1 = peak;
max_pos = j(i);
lookformax = 1;
end
end
end
% % Plot song filtered with edge detector
figure(4)
plot(1/FS:1/FS:N/FS,tedges)
title('Song Filtered With Edge Detector 1')
xlabel('Time (s)')
ylabel('Amplitude')
ylim([-1 1.1])
xlim([0 N/FS])
hold on;
plot(maxtab(:,1)/FS, maxtab(:,2), 'ro')
plot(mintab(:,1)/FS, mintab(:,2), 'ko')
And this is what I included in the GUI script:
[FileName,PathName] = uigetfile({'*.wav'},'Load Wav File');
[x,Fs] = wavread([PathName '/' FileName]);
N = length(x);
handles.x = sum(x,2);
handles.x = x./max(abs(x));
handles.Fs = Fs;
%Gaussian Edge detection filter
P = 20000;
w = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -w .* exp( -(w.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
axes(handles.axes3);
plot(myFilter)
%Peak detection
myFilter = myFilter(:); % create a column vector
x(length(x)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(x)) = 0; %zero pad myFilter
edges =ifft(fft(x).*fft(myFilter));
tedges=edges(P:N+P-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize
maxtab = [];
mintab = [];
j = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN;
max_pos = NaN;
lookformax = 1;
for i=1:length(tedges)
peak = tedges(i:i);
if peak > max1,
max1 = peak;
max_pos = j(i);
end
if peak < min1,
min1 = peak;
min_pos = j(i);
end
if lookformax
if peak < max1-0.09
maxtab = [maxtab ; max_pos max1];
min1 = peak;
min_pos = j(i);
lookformax = 0;
end
else
if peak > min1+0.08
mintab = [mintab ; min_pos min1];
max1 = peak;
max_pos = j(i);
lookformax = 1;
end
end
end
axes(handles.axes4);
plot(1/Fs:1/Fs:N/Fs,tedges)
axis([0 N/Fs -1 1.1]);
What am I doing wrong here?? Really appreciate if someone could help me out here. Thanx in advance...

Finding the maximum peak of an FFT signal

I'm trying to find the maximum amplitude of my frequency domain signal, however the maximum seems to be occurring at around 0 Hz. I tried several methods like subtracting the mean of my signal and also tried using detrend but none seem to work.
clear all;
clear max;
clc;
[song,FS] = wavread('c scale fast.wav');
sound(song,FS);
P = 20000;
N=length(song); % length of song
t=0:1/FS:(N-1)/FS; % define time period
song = sum(song,2);
song=abs(song);
% d = fdesign.bandpass('N,Fst1,Fp1,Fp2,Fst2',120,59,60,1000,1001,44100);
% h = design(d,'window');
% x = filter(h,song);
% Plot time domain signal
figure(1);
subplot(2,1,1)
plot(t,3*song)
title('Wave File')
ylabel('Amplitude')
xlabel('Length (in seconds)')
%ylim([-1.1 1.1])
xlim([0 N/FS])
%----------------------Finding the envelope of the signal-----------------%
% Gaussian Filter
x = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -x .* exp( -(x.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
% Plot Gaussian Filter
subplot(2,1,2)
plot(myFilter)
title('Edge Detection Filter')
% fft convolution
myFilter = myFilter(:); % create a column vector
song(length(song)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(song)) = 0; %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));
tedges=edges(P:N+P-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize
%---------------------------Onset Detection-------------------------------%
% Finding peaks
maxtab = [];
mintab = [];
x = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN;
max_pos = NaN;
lookformax = 1;
for i=1:length(tedges)
peak = tedges(i:i);
if peak > max1,
max1 = peak;
max_pos = x(i);
end
if peak < min1,
min1 = peak;
min_pos = x(i);
end
if lookformax
if peak < max1-0.01
maxtab = [maxtab ; max_pos max1];
min1 = peak;
min_pos = x(i);
lookformax = 0;
end
else
if peak > min1+0.05
mintab = [mintab ; min_pos min1];
max1 = peak;
max_pos = x(i);
lookformax = 1;
end
end
end
% % Plot song filtered with edge detector
figure(2)
plot(1/FS:1/FS:N/FS,tedges)
title('Song Filtered With Edge Detector 1')
xlabel('Time (s)')
ylabel('Amplitude')
ylim([-1 1.1])
xlim([0 N/FS])
hold on;
plot(maxtab(:,1)/FS, maxtab(:,2), 'ro')
plot(mintab(:,1)/FS, mintab(:,2), 'ko')
max_col = maxtab(:,1);
peaks_det = max_col/FS;
No_of_peaks = length(peaks_det);
% song = detrend(song);
%---------------------------Performing FFT--------------------------------%
for i = 2:No_of_peaks
song_seg = song(max_col(i-1):max_col(i)-1);
L = length(song_seg);
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
seg_fft = fft(song_seg,NFFT);%/L;
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])
end
How can I avoid this and correctly identify the maximum in each loop?
Hey I am also plotting the graph showing how many times a frequency occurred.
This is the code I am using:
[wave,freq] = audioread('Our_song.wav');
disp(freq);
dt = 1/ freq;
Stoptime = 1;
t = (0:dt:Stoptime-dt);
n = length(wave)-1;
df = freq/n;
figure;
f = 0:freq/n:99999*freq/n;
ff=abs(fft(wave))/n;
fflength= length(ff);
ffpart=ff(1:100000)
plot(f,ffpart);
I don't know how to output just the maximum.
Tell me if there is any problem in this solution.

Audio signal peak detection using MATLAB

I've been trying to find the peaks of an audio signal. I used "findpeaks" but was not successful. I then came across a peak finding code and merged it with my previous code. However I'm still unable to exctract information about peaks. I need to find the x axis points where peaks occur so I can then perform FFT.
This is the code Ive used:
[song,FS] = wavread('c scale fast.wav');
%P=20000/44100*FS; % length of filter
P = 20000;
N=length(song); % length of song
t=0:1/FS:(N-1)/FS; % define time period
song = sum(song,2);
song=abs(song);
thresh = 0.1;
% Plot time domain signal
figure(1);
subplot(2,1,1)
plot(t,3*song)
title('Wave File')
ylabel('Amplitude')
xlabel('Length (in seconds)')
ylim([0 1.1])
xlim([0 N/FS])
% Gaussian Filter
x = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -x .* exp( -(x.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
% Plot Gaussian Filter
subplot(2,1,2)
plot(myFilter)
title('Edge Detection Filter')
% fft convolution
myFilter = myFilter(:); % create a column vector
song(length(song)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(song)) = 0; %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));
tedges=edges(P/2:N+P/2-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize
% % Plot song filtered with edge detector
figure(2)
plot(1/FS:1/FS:N/FS,tedges)
title('Song Filtered With Edge Detector 1')
xlabel('Time (s)')
ylabel('Amplitude')
ylim([-1 1.1])
xlim([0 N/FS])
hold on;
[song,FS] = wavread('c scale fast.wav');
maxtab = [];
x = (1:length(song))';
mn = Inf;
mx = -Inf;
mnpos = NaN;
mxpos = NaN;
lookformax = 1;
for i=1:length(song)
this = song(i);
if this > mx,
mx = this;
mxpos = x(i);
end
if lookformax
if this < mx-thresh
maxtab = [maxtab ; mxpos mx];
mn = this;
mnpos = x(i);
lookformax = 0;
end
end
end
plot(maxtab(:,1), maxtab(:,2), 'r*')
This is the plot I get;
Can someone help me with this??
Thank you!!!
Its strange that find peak is not working. Are you sure you have also tried the other property related to findpeaks like
[pks,locs] = findpeaks(a,'MINPEAKHEIGHT',0.0005,'MINPEAKDISTANCE',min_peak_distance)
I do not see any reason you not able to find peaks. Plz try again ant tell you just try this code :
a=your_data;
min_peak_distance=as_per_your_need;
[pks,locs] = findpeaks(a,'MINPEAKHEIGHT',0.009,'MINPEAKDISTANCE',min_peak_distance) ; % Find peaks and their indices
% [pks,locs] = findpeaks(a,'MINPEAKDISTANCE',min_peak_distance);
plot(a,'Color','blue'); hold on;
plot(locs,a(locs),'k^','markerfacecolor',[1 0 0]);