TEAP (Toolbox for Emotion Analysis using Physiological Signals) doc
BVP_feat_BPM.m
Go to the documentation of this file.
1 %This file is part of TEAP.
2 %
3 %TEAP is free software: you can redistribute it and/or modify
4 %it under the terms of the GNU General Public License as published by
5 %the Free Software Foundation, either version 3 of the License, or
6 %(at your option) any later version.
7 %
8 %TEAP is distributed in the hope that it will be useful,
9 %but WITHOUT ANY WARRANTY; without even the implied warranty of
10 %MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 %GNU General Public License for more details.
12 %
13 %You should have received a copy of the GNU General Public License
14 %along with TEAP. If not, see <http://www.gnu.org/licenses/>.
15 %
16 %> @file BVP_feat_BPM.m
17 %> @brief Computes the BPM from a BVP signal
18 %
19 %> @param BVPSignal: the BVP signal
20 %
21 %> @retval BPM: the beats per minute
22 %
23 %> @author Copyright Mohammad Soleymani 2013
24 %> @author Copyright Frank Villaro-Dixon, 2014
25 function BPM = BVP_feat_BPM(BVPSignal)
26 
27 
28 %Make sure we have an BVP signal
29 BVPSignal = BVP__assert_type(BVPSignal);
30 
31 data = Signal__get_raw(BVPSignal)';
32 fs = Signal__get_samprate(BVPSignal);
33 
34 
35 if(nargin < 3)
36  methodPeak = 'max';
37 end
38 
39 SizeWindow = round(fs/50);
40 data = data - mean(data);
41 
42 %Filter the data
43 dataS = filtfilt(ones(1, SizeWindow)/SizeWindow, 1, ...
44  [repmat(data(1), SizeWindow, 1); data(:)]);
45 dataS = dataS(SizeWindow+1:end);
46 
47 diffS = diff(dataS);
48 
49 %recherche des pics postif : deriv decroissante = 0
50 listePic = [];
51 for(iSpl = 1:length(diffS)-1)
52  %si il y a une derive == 0 sur le dernier sample elle n'est pas prise en compte
53  if((diffS(iSpl) > 0) && (diffS(iSpl+1) < 0))
54  listePic = [listePic iSpl+(diffS(iSpl) / (diffS(iSpl) - diffS(iSpl+1)))];
55  elseif((diffS(iSpl) == 0) && (diffS(iSpl+1) < 0))
56  listePic = [listePic iSpl];
57  end
58 end
59 
60 %Sure to keep that ?
61 listePic = round(listePic);
62 
63 
64 %Procedure to keep only peaks that are separated by at least 0.5 seconds
65 %other are considered as the same peak and one of the two is selected
66 %according to the chosen method. Also peaks that lie alone in the
67 %first 0.5 seconds are removed (cannot determine which peak it is…)
68 limit = round(0.5*fs);
69 
70 %Remove too early first peakS
71 if((listePic(1) < limit) && (listePic(2) - listePic(1) >= limit))
72  listePic = listePic(2:end);
73 end
74 
75 %remove other peaks
76 iPic = 1;
77 while(iPic <= length(listePic) - 1)
78  %If two peaks are too close keep the one depending on the method
79  if((listePic(iPic+1) - listePic(iPic)) < limit)
80  [dummy, choice] = max([data(listePic(iPic)) data(listePic(iPic+1))]);
81 
82  if(choice == 1)
83  listePic(iPic+1) = [];
84  else
85  listePic(iPic) = [];
86  end
87  else
88  iPic = iPic + 1;
89  end
90 end
91 
92 
93 if(length(listePic) < 2)
94  error('There should be at least 2 peaks to detect');
95 end
96 
97 %Compute bpm from the pic list
98 [BPM delta_t t] = PICtoBPM(listePic, fs);
99 
100 %%%%%BPM = mean(BPM); %And take it's mean
101 
102 end
103 
BVP__assert_type
function BVP__assert_type(in Signal)
PICtoBPM
function PICtoBPM(in listePic, in fe)
Signal__get_raw
function Signal__get_raw(in Signal)
BVP_feat_BPM
function BVP_feat_BPM(in BVPSignal)