Obtain the envelop of a signal using MATLAB

user2482542 picture user2482542 · Jul 22, 2013 · Viewed 26.8k times · Source

I'm trying to extract the peaks of an audio file. I have the following code to extract the envelope of my amplitude spectrum. However I'm not getting the desired output graph. Can someone tell me what adjustment I need to make to get a proper graph. Here's my code:

[song,FS] = wavread('c scale fast.wav');


P=20000/44100*FS;                   % length of filter 
N=length(song);                     % length of song
t=0:1/FS:(N-1)/FS;                  % define time period
% Plot time domain signal
figure(1);
subplot(3,1,1)
plot(t,(3*abs(song)))
title('Wave File')
ylabel('Amplitude')
xlabel('Length (in seconds)')
xlim([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(3,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          
subplot(3,1,3)

plot(1/FS:1/FS:N/FS,tedges)
title('Song Filtered With Edge Detector')
xlabel('Time (s)')
ylabel('Amplitude')
ylim([-1 1.1])
xlim([0 N/FS])

This is the graph i get for the above code and im focusing on the "song filtered with edge detector" plot

This is the graph i get for the above code and im focusing on the "song filtered with edge detector" plot

enter image description here

And this is the "song filtered with edge detector" plot I NEED to get

Answer

craigim picture craigim · Jul 23, 2013

You can use a Hilbert transform to get the envelope. Technically, this returns the analytic signal. You get the envelope with the following line:

envelope = abs(hilbert(Song));

What the Hilbert transform does is to take the fft of the input, zeroes out the negative frequencies, and then does an ifft. The real part of the transform is the original signal, the imaginary part is the transformed signal. The absolute value of the real and imaginary part is the envelope, and the argument (angle(hilbert(Song))) is the instantaneous phase.