You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
2.9 KiB
128 lines
2.9 KiB
#include "HC_Chen_detect.h"
|
|
|
|
bool HC_Chen_detect(float signal)
|
|
{
|
|
ecg_buff[ecg_buff_WR_idx++] = signal;
|
|
sample = ecg_buff_WR_idx;
|
|
ecg_buff_WR_idx %= (M+1);
|
|
|
|
/* High pass filtering */
|
|
if(number_iter < M){
|
|
// first fill buffer with enough points for HP filter
|
|
hp_sum += ecg_buff[ecg_buff_RD_idx];
|
|
hp_buff[hp_buff_WR_idx] = 0;
|
|
}
|
|
else{
|
|
hp_sum += ecg_buff[ecg_buff_RD_idx];
|
|
|
|
int tmp = ecg_buff_RD_idx - M;
|
|
if(tmp < 0){
|
|
tmp += M + 1;
|
|
}
|
|
|
|
hp_sum -= ecg_buff[tmp];
|
|
|
|
float y1 = 0;
|
|
float y2 = 0;
|
|
|
|
tmp = (ecg_buff_RD_idx - ((M+1)/2));
|
|
if(tmp < 0){
|
|
tmp += M + 1;
|
|
}
|
|
|
|
y2 = ecg_buff[tmp];
|
|
|
|
y1 = HP_CONSTANT * hp_sum;
|
|
|
|
hp_buff[hp_buff_WR_idx] = y2 - y1;
|
|
|
|
}
|
|
|
|
// done reading ECG buffer, increment position
|
|
ecg_buff_RD_idx++;
|
|
ecg_buff_RD_idx %= (M+1);
|
|
|
|
// done writing to HP buffer, increment position
|
|
hp_buff_WR_idx++;
|
|
hp_buff_WR_idx %= (N+1);
|
|
|
|
/* Low pass filtering */
|
|
|
|
// shift in new sample from high pass filter
|
|
lp_sum += hp_buff[hp_buff_RD_idx] * hp_buff[hp_buff_RD_idx];
|
|
|
|
if(number_iter < N){
|
|
// first fill buffer with enough points for LP filter
|
|
next_eval_pt = 0;
|
|
}
|
|
else{
|
|
// shift out oldest data point
|
|
int tmp = hp_buff_RD_idx - N;
|
|
if(tmp < 0){
|
|
tmp += N+1;
|
|
}
|
|
|
|
lp_sum -= hp_buff[tmp] * hp_buff[tmp];
|
|
|
|
next_eval_pt = lp_sum;
|
|
}
|
|
|
|
// done reading HP buffer, increment position
|
|
hp_buff_RD_idx++;
|
|
hp_buff_RD_idx %= (N+1);
|
|
|
|
/* Adapative thresholding beat detection */
|
|
// set initial threshold
|
|
if(number_iter < window_size) {
|
|
if(next_eval_pt > treshold) {
|
|
treshold = next_eval_pt;
|
|
}
|
|
++number_iter;
|
|
}
|
|
|
|
// check if detection hold off period has passed
|
|
if(triggered){
|
|
trig_time++;
|
|
|
|
if(trig_time >= DELAY_TIME){
|
|
triggered = false;
|
|
trig_time = 0;
|
|
}
|
|
}
|
|
|
|
// find if we have a new max
|
|
if(next_eval_pt > win_max) win_max = next_eval_pt;
|
|
|
|
// find if we are above adaptive threshold
|
|
if(next_eval_pt > treshold && !triggered) {
|
|
//result.push_back(true);
|
|
|
|
last_qrs_point = sample;
|
|
|
|
triggered = true;
|
|
return true;
|
|
}
|
|
else {
|
|
//result.push_back(false);
|
|
}
|
|
|
|
// adjust adaptive threshold using max of signal found
|
|
// in previous window
|
|
if(win_idx++ >= window_size){
|
|
// weighting factor for determining the contribution of
|
|
// the current peak value to the threshold adjustment
|
|
float gamma = (0.2f+0.15f)/2.0f; // 0.15~0.2
|
|
|
|
// forgetting factor -
|
|
// rate at which we forget old observations
|
|
float alpha = 0.01f + ( ((float) rand() / (float) RAND_MAX) * ((0.1f - 0.01f))); // 0~1
|
|
//float alpha = 1.0f*exp(-0.00005f*(sample - last_qrs_point));
|
|
|
|
treshold = alpha * gamma * win_max + (1.0f - alpha) * treshold;
|
|
|
|
// reset current window ind
|
|
win_idx = 0;
|
|
win_max = -10000000;
|
|
}
|
|
return false;
|
|
}
|