Mercurial > hg > aim92
view tools/filt1.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line source
/* filt1.c 1st order LP filter using an exponential smoother (recursive "leaky integrator" filter) The n'th recursive update is: a) y[n] = a.y[n-1] + x[n] recursive sum b) y[n] = a.y[n-1] + (1-a).x[n] recursive mean where decay constant a = exp(-Ts/T) and Ts is sample interval in seconds T is decay time-constant in seconds The 1st order LP filter is an exponential window which decays into the past. With decay constant a=1 there is infinite memory because it does not decay. The result is either a steadily accumulating sum or mean. (A zero mean is assumed). With 0 < a < 1 there is a finite decaying memory. The smaller `a', the smaller the memory (it decays faster). With a = 0 the filter output is identical with its input. The window width parameter is the time-constant parameter. The half life of the exponential window is given by -T.ln(0.5) = 0.693T ie. for a given time constant, T secs, the window decays to half of its current value in a period of 0.693T secs. (Thus T can be set to accomodate an expected period). When the time-constant parameter is given with time units (s or ms) then it is converted to a decay constant using a = exp(-Ts/T). Otherwise it is taken to be the decay constant directly. */ #include <stdio.h> #include <math.h> #include "options.h" #include "units.h" #include "strmatch.h" char applic[] = "1st order low-pass filter using exponential smoother." ; static char *helpstr, *debugstr, *sampstr, *tcstr, *destr ; static Options option[] = { { "help" , "off" , &helpstr , "help" , DEBUG }, { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, { "samplerate", "20kHz" , &sampstr , "Samplerate " , VAL }, { "tc" , "3ms" , &tcstr , "Decay time constant" , VAL }, { "de" , "mean" , &destr , "Difference equation" , VAL }, ( char * ) 0 } ; int samplerate ; double a ; /* decay constant */ main (argc, argv) int argc; char **argv; { FILE *fp ; short x, y ; int morehelp() ; fp = openopts( option,argc,argv ) ; if ( !isoff( helpstr ) ) helpopts1( helpstr, argv[0], applic, option, morehelp ) ; samplerate = to_Hz( sampstr ) ; if ( Units( tcstr ) ) a = exp( -(double)( 1. / ( samplerate * to_s( tcstr, samplerate ) ) ) ) ; else a = (double)atof( tcstr ) ; y = 0 ; /* initialization */ if ( iststr( destr, "mean" ) ) while ( fread( &x, sizeof(short), 1, fp ) ) { y = a * y + ( 1 - a ) * x ; fwrite( &y, sizeof(short), 1, stdout ) ; } else if ( iststr( destr, "sum" ) ) while ( fread( &x, sizeof(short), 1, fp ) ) { y = a * y + x ; fwrite( &y, sizeof(short), 1, stdout ) ; } else { fprintf( stderr,"unknown de [%s]\n", destr ) ; exit( 1 ) ; } fclose( fp ); } /* Return 1 if the str has appended units. Otherwise return 0. */ Units(str) char *str ; { char *eptr = str + strlen( str ) ; if( isdigit( *--eptr ) ) return 0 ; /* last char is digit, so no units */ else return 1 ; } morehelp() { fprintf(stderr,"\nde: \n"); fprintf(stderr," sum y[n] = a.y[n-1] + x[n] \n"); fprintf(stderr," mean y[n] = a.y[n-1] + (1-a).x[n] (unity steady-state gain)\n"); exit( 1 ) ; }