📄 r_dec.c
字号:
*****************************************************************************/
#include "bdac.h"
#include <STDIO.H>
#include <STDLIB.H>
#define ISO_LENGTH1 BEAT_MS50
#define ISO_LENGTH2 BEAT_MS80
#define ISO_LIMIT 20
// Local prototypes.
int IsoCheck(int *data, int isoLength);
/****************************************************************
等电位线的确定
*****************************************************************/
int IsoCheck(int *data, int isoLength)
{
int i, max, min ;
for(i = 1, max=min = data[0]; i < isoLength; ++i)
{
if(data[i] > max)
max = data[i] ;
else if(data[i] < min)
min = data[i] ;
}
if(max - min < ISO_LIMIT)
return(1) ;
return(0) ;
}
/**********************************************************************
QRS 波的起点和终点,极性,等电位水平
************************************************************************/
#define INF_CHK_N BEAT_MS40
void AnalyzeBeat(int *beat, int *onset, int *offset, int *isoLevel,
int *beatBegin, int *beatEnd, int *amp)
{
int maxSlope = 0, maxSlopeI, minSlope = 0, minSlopeI ;
int maxV, minV ;
int isoStart, isoEnd ;
int slope, i ;
// Search back from the fiducial mark to find the isoelectric
// region preceeding the QRS complex.
for(i = FIDMARK-ISO_LENGTH2; (i > 0) && (IsoCheck(&beat[i],ISO_LENGTH2) == 0); --i) ;
// If the first search didn't turn up any isoelectric region, look for
// a shorter isoelectric region.
if(i == 0)
{
for(i = FIDMARK-ISO_LENGTH1; (i > 0) && (IsoCheck(&beat[i],ISO_LENGTH1) == 0); --i) ;
isoStart = i + (ISO_LENGTH1 - 1) ;
}
else isoStart = i + (ISO_LENGTH2 - 1) ;
// Search forward from the R-wave to find an isoelectric region following
// the QRS complex.
for(i = FIDMARK; (i < BEATLGTH) && (IsoCheck(&beat[i],ISO_LENGTH1) == 0); ++i) ;
isoEnd = i ;
// Find the maximum and minimum slopes on the
// QRS complex.
i = FIDMARK-BEAT_MS150 ;
maxSlope = maxSlope = beat[i] - beat[i-1] ;
maxSlopeI = minSlopeI = i ;
for(; i < FIDMARK+BEAT_MS150; ++i)
{
slope = beat[i] - beat[i-1] ;
if(slope > maxSlope)
{
maxSlope = slope ;
maxSlopeI = i ;
}
else if(slope < minSlope)
{
minSlope = slope ;
minSlopeI = i ;
}
}
// Use the smallest of max or min slope for search parameters.
if(maxSlope > -minSlope)
maxSlope = -minSlope ;
else minSlope = -maxSlope ;
if(maxSlopeI < minSlopeI)
{
// Search back from the maximum slope point for the QRS onset.
for(i = maxSlopeI;
(i > 0) && ((beat[i]-beat[i-1]) > (maxSlope >> 2)); --i) ;
*onset = i-1 ;
// Check to see if this was just a brief inflection.
for(; (i > *onset-INF_CHK_N) && ((beat[i]-beat[i-1]) <= (maxSlope >>2)); --i) ;
if(i > *onset-INF_CHK_N)
{
for(;(i > 0) && ((beat[i]-beat[i-1]) > (maxSlope >> 2)); --i) ;
*onset = i-1 ;
}
i = *onset+1 ;
// Check to see if a large negative slope follows an inflection.
// If so, extend the onset a little more.
for(;(i > *onset-INF_CHK_N) && ((beat[i-1]-beat[i]) < (maxSlope>>2)); --i);
if(i > *onset-INF_CHK_N)
{
for(; (i > 0) && ((beat[i-1]-beat[i]) > (maxSlope>>2)); --i) ;
*onset = i-1 ;
}
// Search forward from minimum slope point for QRS offset.
for(i = minSlopeI;
(i < BEATLGTH) && ((beat[i] - beat[i-1]) < (minSlope >>2)); ++i);
*offset = i ;
// Make sure this wasn't just an inflection.
for(; (i < *offset+INF_CHK_N) && ((beat[i]-beat[i-1]) >= (minSlope>>2)); ++i) ;
if(i < *offset+INF_CHK_N)
{
for(;(i < BEATLGTH) && ((beat[i]-beat[i-1]) < (minSlope >>2)); ++i) ;
*offset = i ;
}
i = *offset ;
// Check to see if there is a significant upslope following
// the end of the down slope.
for(;(i < *offset+BEAT_MS40) && ((beat[i-1]-beat[i]) > (minSlope>>2)); ++i);
if(i < *offset+BEAT_MS40)
{
for(; (i < BEATLGTH) && ((beat[i-1]-beat[i]) < (minSlope>>2)); ++i) ;
*offset = i ;
// One more search motivated by PVC shape in 123.
for(; (i < *offset+BEAT_MS60) && (beat[i]-beat[i-1] > (minSlope>>2)); ++i) ;
if(i < *offset + BEAT_MS60)
{
for(;(i < BEATLGTH) && (beat[i]-beat[i-1] < (minSlope>>2)); ++i) ;
*offset = i ;
}
}
}
else
{
// Search back from the minimum slope point for the QRS onset.
for(i = minSlopeI;
(i > 0) && ((beat[i]-beat[i-1]) < (minSlope >> 2)); --i) ;
*onset = i-1 ;
// Check to see if this was just a brief inflection.
for(; (i > *onset-INF_CHK_N) && ((beat[i]-beat[i-1]) >= (minSlope>>2)); --i) ;
if(i > *onset-INF_CHK_N)
{
for(; (i > 0) && ((beat[i]-beat[i-1]) < (minSlope>>2));--i) ;
*onset = i-1 ;
}
i = *onset+1 ;
// Check for significant positive slope after a turning point.
for(;(i > *onset-INF_CHK_N) && ((beat[i-1]-beat[i]) > (minSlope>>2)); --i);
if(i > *onset-INF_CHK_N)
{
for(; (i > 0) && ((beat[i-1]-beat[i]) < (minSlope>>2)); --i) ;
*onset = i-1 ;
}
// Search forward from maximum slope point for QRS offset.
for(i = maxSlopeI;
(i < BEATLGTH) && ((beat[i] - beat[i-1]) > (maxSlope >>2)); ++i) ;
*offset = i ;
// Check to see if this was just a brief inflection.
for(; (i < *offset+INF_CHK_N) && ((beat[i] - beat[i-1]) <= (maxSlope >> 2)); ++i) ;
if(i < *offset+INF_CHK_N)
{
for(;(i < BEATLGTH) && ((beat[i] - beat[i-1]) > (maxSlope >>2)); ++i) ;
*offset = i ;
}
i = *offset ;
// Check to see if there is a significant downslope following
// the end of the up slope.
for(;(i < *offset+BEAT_MS40) && ((beat[i-1]-beat[i]) < (maxSlope>>2)); ++i);
if(i < *offset+BEAT_MS40)
{
for(; (i < BEATLGTH) && ((beat[i-1]-beat[i]) > (maxSlope>>2)); ++i) ;
*offset = i ;
}
}
// If the estimate of the beginning of the isoelectric level was
// at the beginning of the beat, use the slope based QRS onset point
// as the iso electric point.
if((isoStart == ISO_LENGTH1-1)&& (*onset > isoStart)) // ** 4/19 **
isoStart = *onset ;
// Otherwise, if the isoelectric start and the slope based points
// are close, use the isoelectric start point.
else if(*onset-isoStart < BEAT_MS50)
*onset = isoStart ;
// If the isoelectric end and the slope based QRS offset are close
// use the isoelectic based point.
if(isoEnd - *offset < BEAT_MS50)
*offset = isoEnd ;
*isoLevel = beat[isoStart] ;
// Find the maximum and minimum values in the QRS.
for(i = *onset, maxV = minV = beat[*onset]; i < *offset; ++i)
if(beat[i] > maxV)
maxV = beat[i] ;
else if(beat[i] < minV)
minV = beat[i] ;
// If the offset is significantly below the onset and the offset is
// on a negative slope, add the next up slope to the width.
if((beat[*onset]-beat[*offset] > ((maxV-minV)>>2)+((maxV-minV)>>3)))
{
// Find the maximum slope between the finish and the end of the buffer.
for(i = maxSlopeI = *offset, maxSlope = beat[*offset] - beat[*offset-1];
(i < *offset+BEAT_MS100) && (i < BEATLGTH); ++i)
{
slope = beat[i]-beat[i-1] ;
if(slope > maxSlope)
{
maxSlope = slope ;
maxSlopeI = i ;
}
}
// Find the new offset.
if(maxSlope > 0)
{
for(i = maxSlopeI;
(i < BEATLGTH) && (beat[i]-beat[i-1] > (maxSlope>>1)); ++i) ;
*offset = i ;
}
}
for(i = FIDMARK-BEAT_MS250;
(i >= BEAT_MS80) && (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 0); --i) ;
*beatBegin = i ;
if(*beatBegin == FIDMARK-BEAT_MS250)
{
for(; (i < *onset-BEAT_MS50) &&
(IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 1); ++i) ;
*beatBegin = i-1 ;
}
// Rev 1.1
else if(*beatBegin == BEAT_MS80 - 1)
{
for(; (i < *onset) && (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 0); ++i);
if(i < *onset)
{
for(; (i < *onset) && (IsoCheck(&beat[i-BEAT_MS80],BEAT_MS80) == 1); ++i) ;
if(i < *onset)
*beatBegin = i-1 ;
}
}
for(i = FIDMARK+BEAT_MS300;
(i < BEATLGTH) && (IsoCheck(&beat[i],BEAT_MS80) == 0); ++i) ;
*beatEnd = i ;
// If the signal was isoelectric at 300 ms. search backwards.
/* if(*beatEnd == FIDMARK+30)
{
for(; (i > *offset) && (IsoCheck(&beat[i],8) != 0); --i) ;
*beatEnd = i ;
}
*/
// Calculate beat amplitude.
maxV=minV=beat[*onset] ;
for(i = *onset; i < *offset; ++i)
if(beat[i] > maxV)
maxV = beat[i] ;
else if(beat[i] < minV)
minV = beat[i] ;
*amp = maxV-minV ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -