Created
January 6, 2011 22:47
-
-
Save marknorgren/768760 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* fir.c | |
* SEIS742 - May2010 | |
*/ | |
#include <math.h> | |
//#include <filter.h> | |
#include "normal.h" | |
#include "flat.h" | |
#include "tachy.h" | |
#include "defib.h" | |
#include <stdio.h> | |
#include <string.h> | |
#define ARRAY_SIZE 1024 // length of the input vector | |
#define NUM_TAPS 15 // number of filter coefficients | |
//#define NORMAL_IN_SIZE 1024 | |
typedef enum { false, true } bool; | |
const long double coefs_doub[NUM_TAPS] = { | |
0.000247809018765355, | |
0.002273715947318348, | |
0.010468194559522206, | |
0.031816282592572021, | |
0.070964079390059054, | |
0.122467424372272940, | |
0.168279086570308960, | |
0.186803245199647250, | |
0.168279086570308960, | |
0.122467424372272940, | |
0.070964079390059054, | |
0.031816282592572021, | |
0.010468194559522206, | |
0.002273715947318348, | |
0.000247809018765355 | |
}; | |
void runFIR(char inputType[50], long double dataArray[], int dataArraySize, | |
int samplesPerSecond); | |
long double filteredDataMean(long double dataArray[], int dataArraySize); | |
long double filteredDataStdDeviation(long double dataArray[], | |
int dataArraySize, long double dataMean); | |
long double fir_split(long double input, int ntaps, | |
const long double FIRCoeffs[], | |
long double delayBuffer[], | |
int *p_state); | |
int numTaps = NUM_TAPS; | |
int main() | |
{ | |
char normalLabel[100] = "NORMAL_"; | |
char defibLabel[100] = "DEFIB_"; | |
char flatLabel[100] = "FLAT_"; | |
char tachyLabel[100] = "TACY_"; | |
printf("************************************************************\r\n"); | |
printf("*** NORMAL ***\r\n"); | |
runFIR(normalLabel, IN_NORMAL, NORMAL_IN_SIZE, NORMAL_SAMPLES_PER_SECOND); | |
printf("************************************************************\r\n"); | |
printf("\r\n\r\n"); | |
printf("************************************************************\r\n"); | |
printf("*** DEFIB ***\r\n"); | |
runFIR(defibLabel, IN_DEFIB, DEFIB_IN_SIZE, DEFIB_SAMPLES_PER_SECOND); | |
printf("************************************************************\r\n"); | |
printf("\r\n\r\n"); | |
printf("************************************************************\r\n"); | |
printf("*** FLAT ***\r\n"); | |
runFIR(flatLabel, IN_FLAT, FLAT_IN_SIZE, FLAT_SAMPLES_PER_SECOND); | |
printf("************************************************************\r\n"); | |
printf("\r\n\r\n"); | |
printf("************************************************************\r\n"); | |
printf("*** TACHY ***\r\n"); | |
runFIR(tachyLabel, IN_TACHY, TACHY_IN_SIZE, TACHY_SAMPLES_PER_SECOND); | |
printf("************************************************************\r\n"); | |
printf("%s", defibLabel); | |
scanf(" "); | |
} | |
/*********************************************************** | |
/* Data analysis | |
/**********************************************************/ | |
void runFIR(char inputType[50], long double dataArray[], int dataArraySize, | |
int samplesPerSecond){ | |
int i; | |
int filterState=0; //tracks filter coeficient location | |
long double filteredDataArray[ARRAY_SIZE]={0.0}; | |
long double delayLineArray[NUM_TAPS] = {0}; | |
int rWaveCount=0; //count of peaks detected in array | |
long double rWavePeakLocation[100]={0.0}; | |
long double deltaT[25]={0.0}; | |
bool atPeak=false; | |
bool slopePositive=false; | |
long double slopeValue=0; | |
long double peakLevel; //peak of R wave (mu+sigma) | |
long double muValue=0; | |
long double sigmaValue=0; | |
long double muDeltaT; | |
long double sigmaDeltaT; | |
/*DEBUG FILE*/ | |
FILE *ifp, *ofp; | |
char filteredOutput[] = "filteredOutput.txt"; | |
char inputSamples[] = "inputSamples.txt"; | |
char temp[100] = ""; | |
char outFileName[100] = ""; | |
char inFileName[100] = ""; | |
strcat(temp, inputType); | |
strcat(inputType, filteredOutput); | |
strcat(outFileName, inputType); | |
strcat(temp, inputSamples); | |
strcat(inFileName, temp); | |
printf("%s", inputSamples); | |
ofp = fopen(outFileName, "w"); | |
ifp = fopen(inFileName, "w"); | |
if (ifp == NULL) printf("Can't open input file\r\n"); | |
if (ofp == NULL) printf("Can't open output file\r\n"); | |
/*END DEBUG FILE*/ | |
for(i=0;i<dataArraySize;i++) | |
{ | |
//RUN FILTER | |
filteredDataArray[i] = fir_split(dataArray[i], numTaps, coefs_doub, | |
delayLineArray, &filterState); | |
/* DEBUG - Output to file - Input Data and Filtered Data */ | |
//fprintf(ofp, "%g, %g\n",IN_NORMAL[i], myOutput[i]); | |
fprintf(ofp, "%g\n",filteredDataArray[i]); | |
fprintf(ifp, "%g\n", dataArray[i]); | |
//printf("NormalIn: %f - Out: %.17g\r\n", dataArray[i], | |
//filteredDataArray[i]); | |
} | |
fclose(ofp); | |
fclose(ifp); | |
//find mean - mu | |
muValue = filteredDataMean(filteredDataArray, dataArraySize); | |
printf("muValue: %.18g\r\n", muValue); | |
//find std deviation - sigma | |
sigmaValue = filteredDataStdDeviation(filteredDataArray, dataArraySize, | |
muValue); | |
printf("sigmaValue: %.18g\r\n", sigmaValue); | |
//peak level becomes (mu+sigma) | |
peakLevel = muValue+sigmaValue; | |
printf("peakLevel: %.18g\r\n", peakLevel); | |
/* for loop */ | |
for(i=NUM_TAPS;i<dataArraySize;i++){ | |
if((filteredDataArray[i] > peakLevel) && atPeak==0){ | |
//found R wave, but not at peak | |
//printf("FOUND R WAVE at index: %i -", i); | |
//calculate slopes until negative slope is found; | |
//tracing up the r wave | |
if(i<dataArraySize) | |
slopeValue = (filteredDataArray[i+1]-filteredDataArray[i]); | |
//printf("slopeValue %g\r\n", slopeValue); | |
if(slopeValue>0) slopePositive=true; | |
else slopePositive = false; | |
if(slopePositive && atPeak){ | |
printf("Climbing R Wave\r\n"); | |
} | |
else { //at peak | |
if (!slopePositive && !atPeak){ | |
//printf("At Peak\r\n"); | |
if((filteredDataArray[i]-peakLevel)>muValue){ | |
rWavePeakLocation[rWaveCount] = | |
//holds time of rwave peak | |
((long double)i/samplesPerSecond); | |
/*printf("Peak found at %i, time %f, amplitude %g\r\n", | |
i, | |
rWavePeakLocation[rWaveCount], | |
filteredDataArray[i]);*/ | |
atPeak=true; | |
rWaveCount++; | |
} | |
} | |
} | |
} | |
if(atPeak && (filteredDataArray[i] < peakLevel)){ | |
atPeak=false; | |
slopeValue=0.0; | |
} | |
} | |
/*for loop*/ | |
// | |
printf("R Wave Count: %i\r\n", rWaveCount); | |
for(i=0;i<(rWaveCount-1);i++){ | |
deltaT[i] = rWavePeakLocation[i+1]-rWavePeakLocation[i]; | |
} | |
muDeltaT = filteredDataMean(deltaT, rWaveCount-1); | |
sigmaDeltaT = filteredDataStdDeviation(deltaT, rWaveCount-1, muDeltaT); | |
printf("Mean R wave peaks: %g\r\n", muDeltaT); | |
printf("Std Deviation of dT R wave peaks: %g\r\n", sigmaDeltaT); | |
if (sigmaDeltaT > 10) { | |
printf("SHOCK!\r\n"); | |
} | |
if (muDeltaT < 0.5 || muDeltaT > 6) { | |
printf("SHOCK!\r\n"); | |
}else | |
{ | |
printf("no shock\r\n"); | |
} | |
return; | |
} | |
/**************************************************************************** | |
* | |
* Copyright 2000 by Grant R. Griffin | |
* | |
* Thanks go to contributors of comp.dsp for teaching me some of these | |
* techniques, and to Jim Thomas for his review and great suggestions. | |
* | |
* The Wide Open License (WOL) | |
* | |
* Permission to use, copy, modify, distribute and sell this software and its | |
* documentation for any purpose is hereby granted without fee, provided that | |
* the above copyright notice and this license appear in all source copies. | |
* THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF | |
* ANY KIND. See http://www.dspguru.com/wol.htm for more information. | |
* | |
* fir_split: This splits the calculation into two parts so the circular | |
* buffer logic doesn't have to be done inside the calculation loop. | |
*****************************************************************************/ | |
long double fir_split(long double input, int ntaps, | |
const long double firCoeffs[], long double delayBuffer[], | |
int *p_state) | |
{ | |
int ii, end_ntaps, state = *p_state; | |
long double accum; | |
long double const *p_h; | |
long double *p_z; | |
/* setup the filter */ | |
accum = 0; | |
p_h = firCoeffs; //h = filterCoeffs | |
/* calculate the end part */ | |
p_z = delayBuffer + state; | |
*p_z = input; | |
end_ntaps = ntaps - state; | |
for (ii = 0; ii < end_ntaps; ii++) { | |
accum += *p_h++ * *p_z++; | |
} | |
/* calculate the beginning part */ | |
p_z = delayBuffer; | |
for (ii = 0; ii < state; ii++) { | |
accum += *p_h++ * *p_z++; | |
} | |
/* decrement the state, wrapping if below zero */ | |
if (--state < 0) { | |
state += ntaps; | |
} | |
*p_state = state; /* pass new state back to caller */ | |
return accum; | |
} | |
//calculate mean of buffer data - mu | |
long double filteredDataMean(long double dataArray[], int dataArraySize){ | |
long double accum=0.0; | |
int i=0; | |
for(i=0;i<dataArraySize;i++){ | |
accum += dataArray[i]; | |
} | |
return (accum/(long double)dataArraySize); | |
} | |
//calculate std deviation of buffer data - sigma | |
long double filteredDataStdDeviation(long double dataArray[], int dataArraySize, | |
long double dataMean){ | |
int i=0; | |
long double accum=0.0, ii=0.0; | |
for(i=0;i<dataArraySize;i++){ | |
ii = ((dataArray[i]-dataMean)); | |
accum += (ii*ii); | |
} | |
return (sqrt((accum/(long double)dataArraySize))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment