0

From an audio stream vector in Matlab I am trying to identify the time of onset and finish of audible events that occur multiple times within the time series data.

I am very much a novice with Matlab, but I have written code which identifies the peak and location of the event, however, I need to get the start of the event relative to a user defined threshold which occurs several tens of milliseconds before the peak.

Here is the code I am using at the moment:

function [emg] = calcPeaks(EMG, thresh)
%Rectify and downsample data 

emg = resample(abs(hilbert(EMG)),1000,10000); 
%Low Pass Filter 
[b,a]=butter(8,0.01,'low');
emg=filtfilt(b,a,emg);

%Plot the processed vector 
plot (emg); hold on;

%Find maximum for each Peak and Location
[pks,locs] = findpeaks(emg(1:end-2000),'minpeakheight',thresh);

plot(locs, emg(locs), 'ko'); hold on;

%Find Crossings above threshold
[FindCross] = find(emg(1:end-2000) > thresh);
[Gaps] = find(diff(FindCross)> thresh);
plot(FindCross, emg(FindCross), 'ro');
plot(Gaps, emg(Gaps), 'bo');

I tried to post an image of the datat but I don't have enough reputation :(

bla
  • 25,846
  • 10
  • 70
  • 101
MKW
  • 1
  • 1
  • So what is the question or problem? – Bas Swinckels Oct 04 '13 at 08:24
  • Hi Bas, thanks for taking an interest. Let me try and clarifiy. Even though I have the position of the maxima of the event, the Maxima is relatively far away from the start of the event. I need to be able to determine the actual start and end, which I was hoping to do by acquiring the indices when the signal passes and returns a threshold. – MKW Oct 04 '13 at 09:32

1 Answers1

0

This should be getting you close to what you want (although same thresh for both is probably not what you intend):

[FindCross] = find(emg(1:end-2000) > thresh); %thresh is your minimum volume
[Gaps] = find(diff(FindCross)> thresh2); % thresh2 is related to the timing of events

However, note that this only finds gaps between areas which are above your noise level threshold, so won't locate the first event (presuming at start of data you are below the threshold).

A simple way to do this sort of thing is to threshold and then use diff to look for rising and falling edges in the thresholded data.

emg2 = emg > thresh; %emg2 = 1 and 0 for event / non event
demg = diff(emg2); % contains 0, -1, 1
rise = find(demg>0)+1; %+1 because of how diff works
fall = find(demg<0);

rise should then contain the positions where emg goes from below threshold to above threshold. If the data is sufficiently noisy, this could contain false positives, so you may want to then filter those results with additional criteria - e.g. check that after the rise the data stays above threshold for some minimum period.


The problem with doing it by the method you're using to find gaps is the following. Presume your data looks like this, where 0 is below threshold and 1 above threshold: 000111000111000. That is, our first event starts at index 4 and finishes at index 6, and the second starts at index 10 and ends at index 12.

emgT = find(emg > thresh);

This finds all the places where our data = 1, so emgT = [4,5,6,10,11,12]

emgD = diff(emgT); 

This takes the difference between emgT(n+1), and emgT(n) - since there's no n+1 for the final datapoint, the output is one smaller than emgT. Our output is [1 1 4 1 1] - that is, it will find the gap between the two events, but not the gap between the start of the file and the first event, or the gap between the last event and the end of the file.

nkjt
  • 7,825
  • 9
  • 22
  • 28
  • Thanks. I am now able to detect the rise in the signal. I have modified the code to give the fall in the signal. However, I have one issue which doesn't seem to make sense to me. The vectors for the rise and fall of the signal are of a different size, e.g Rise = 200 elements, emgTT = 199. My code for the fall of the signal seems to miss the last event for some reason. If you have a work around for that so I can perform operations with the two vectors I would be really grateful. emgT = find(emg > thresh); emgD = diff(emgT); emgDT = emgD > 50; emgTT = emgT(emgDT); – MKW Oct 04 '13 at 11:43