tomwalters@0: /*************************************************************************** tomwalters@0: units.c tomwalters@0: --------- tomwalters@0: Return binary doubles for given string values, according to units. tomwalters@0: Units are specified by the final char: tomwalters@0: p sample points. tomwalters@0: s seconds. tomwalters@0: ms milliseconds tomwalters@0: Hz Hertz. tomwalters@0: kHz KiloHertz tomwalters@0: erb equivalent rectangular bandwidth [Hz] tomwalters@0: tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include "units.h" tomwalters@0: #include "strmatch.h" tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the units index number of the best matching units at the tail of tomwalters@0: string `s'. Return -1 if no units are found. tomwalters@0: */ tomwalters@0: tomwalters@0: int unitindex( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: int i ; tomwalters@0: tomwalters@0: if ( ( i = strnumspn( s ) ) == 0 ) { /* case of no digits found */ tomwalters@0: fprintf( stderr, "bad value [%s]\n", s ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: if ( i == strlen( s ) ) tomwalters@0: return (-1) ; /* case of no units found */ tomwalters@0: tomwalters@0: switch ( i = listindex( units, s+i ) ) { tomwalters@0: case (-1) : fprintf(stderr,"unknown units [%s]\n", s ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: case (-2) : fprintf(stderr,"ambiguous units [%s]\n", s ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: return i ; /* index of units */ tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return a ptr to the units string at the tail of string `s'. tomwalters@0: Otherwise return a ptr to the null terminator of `s' if no units are found. tomwalters@0: */ tomwalters@0: tomwalters@0: char *unitstr( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: unitindex( s ) ; /* check for valid (or no) units */ tomwalters@0: return ( strnumptr( s ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Search the end of the given string for units (such as ms, kHz, etc). tomwalters@0: Delete any units found by overwriting the start of the units string with '\0'. tomwalters@0: */ tomwalters@0: tomwalters@0: stripunits( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: *( unitstr( s ) ) = '\0' ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return an allocated string to the square root of the given value with original tomwalters@0: units appended. tomwalters@0: */ tomwalters@0: tomwalters@0: char *sqrt_units( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: char s1[64] ; tomwalters@0: tomwalters@0: sprintf( s1, "%.2f%s", sqrt( (double)atof( s ) ), unitstr( s ) ) ; tomwalters@0: return ( strcpy( (char *)malloc( strlen( s1 ) + 1 ), s1 ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the type of a : INT, FLOAT, or 0 (if not a number). tomwalters@0: = [-][.] tomwalters@0: where either, but not both, of the digit strings may be empty. tomwalters@0: */ tomwalters@0: tomwalters@0: int numbertype( str ) tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: if ( strnumspn( str ) == 0 ) return 0 ; tomwalters@0: if ( strchr( str, '.' ) == (char *)0 ) return INT ; tomwalters@0: else return FLOAT ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return 1 if str is an int, otherwise return 0. tomwalters@0: */ tomwalters@0: tomwalters@0: int isint( str ) tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: if ( numbertype( str ) == INT ) return 1 ; tomwalters@0: return 0 ; tomwalters@0: } tomwalters@0: tomwalters@0: /* tomwalters@0: Return 1 if str is a float, otherwise return 0. tomwalters@0: */ tomwalters@0: tomwalters@0: int isfloat( str ) tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: if ( numbertype( str ) == FLOAT ) return 1 ; tomwalters@0: return 0 ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Units converters. tomwalters@0: Generally called: to_ where is the output units. tomwalters@0: Input strings without units have `default' units. tomwalters@0: */ tomwalters@0: tomwalters@0: double to_Hz( str, samplerate ) /* default units Hz */ tomwalters@0: char *str ; tomwalters@0: int samplerate ; tomwalters@0: { tomwalters@0: switch ( unitindex( str ) ) { tomwalters@0: case (-1) : return atof( str ) ; tomwalters@0: case 0 : return ( (double)samplerate / atof( str ) ) ; tomwalters@0: case 1 : return ( 1. / atof( str ) ) ; tomwalters@0: case 2 : return ( 1000. / atof( str ) ) ; tomwalters@0: case 3 : return atof( str ) ; tomwalters@0: case 4 : return ( atof( str ) * 1000 ) ; tomwalters@0: case 5 : return ( ( exp( (double)(atof( str ) / 9.265 )) - 1 ) * 9.265 * 24.7 ) ; tomwalters@0: default : fprintf(stderr, "can't convert [%s] to Hz\n", str ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: double to_kHz( str, samplerate ) /* default units Hz */ tomwalters@0: char *str ; tomwalters@0: int samplerate ; tomwalters@0: { tomwalters@0: switch ( unitindex( str ) ) { tomwalters@0: case (-1) : return ( atof( str ) * .001 ) ; tomwalters@0: case 0 : return ( ( (double)samplerate / atof( str ) ) * 0.001 ) ; tomwalters@0: case 1 : return ( ( 1. / atof( str ) ) * 0.001 ) ; tomwalters@0: case 2 : return ( 1. / atof( str ) ) ; tomwalters@0: case 3 : return ( atof( str ) * .001 ) ; tomwalters@0: case 4 : return atof( str ) ; tomwalters@0: case 5 : return ( ( exp( (double)(atof( str ) / 9.265 )) - 1 ) * 9.265 * 24.7 * .001 ) ; tomwalters@0: default : fprintf(stderr, "can't convert [%s] to kHz\n", str ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: double to_erb( str ) /* default units erb */ tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: switch ( unitindex( str ) ) { tomwalters@0: case (-1) : return atof( str ) ; tomwalters@0: case 3 : return ( 9.265 * log( (double)(1 + atof( str )/(9.265*24.7)) ) ) ; tomwalters@0: case 4 : return ( 9.265 * log( (double)(1 + (1000*atof( str ))/(9.265*24.7)) ) ) ; tomwalters@0: case 5 : return atof( str ) ; tomwalters@0: default : fprintf(stderr, "can't convert [%s] to erb\n", str ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: double to_p( str, samplerate ) /* default units p */ tomwalters@0: char *str ; tomwalters@0: int samplerate ; tomwalters@0: { tomwalters@0: switch ( unitindex( str ) ) { tomwalters@0: case (-1) : return atof( str ) ; tomwalters@0: case 0 : return atof( str ) ; tomwalters@0: case 1 : return ( atof( str ) * samplerate ) ; tomwalters@0: case 2 : return ( atof( str ) * samplerate * .001 ) ; tomwalters@0: case 3 : return ( samplerate / atof( str ) ) ; tomwalters@0: case 4 : return ( samplerate / ( 1000 * atof( str ) ) ) ; tomwalters@0: default : fprintf(stderr, "can't convert [%s] to samples\n", str ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: double to_s( str, samplerate ) /* default units p (sample points) */ tomwalters@0: char *str ; tomwalters@0: int samplerate ; tomwalters@0: { tomwalters@0: switch ( unitindex( str ) ) { tomwalters@0: case (-1) : return ( atof( str ) / samplerate ) ; tomwalters@0: case 0 : return ( atof( str ) / samplerate ) ; tomwalters@0: case 1 : return atof( str ) ; tomwalters@0: case 2 : return ( atof( str ) * .001 ) ; tomwalters@0: case 3 : return ( 1. / atof( str ) ) ; tomwalters@0: case 4 : return ( 1. / ( 1000 * atof( str ) ) ) ; tomwalters@0: default : fprintf(stderr, "can't convert [%s] to secs\n", str ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: double to_ms( str, samplerate ) /* default units p */ tomwalters@0: char *str ; tomwalters@0: int samplerate ; tomwalters@0: { tomwalters@0: switch ( unitindex( str ) ) { tomwalters@0: case (-1) : return ( atof( str ) * 1000 / samplerate ) ; tomwalters@0: case 0 : return ( atof( str ) * 1000 / samplerate ) ; tomwalters@0: case 1 : return ( atof( str ) * 1000 ) ; tomwalters@0: case 2 : return atof( str ) ; tomwalters@0: case 3 : return ( 1000. / atof( str ) ) ; tomwalters@0: case 4 : return ( 1. / atof( str ) ) ; tomwalters@0: default : fprintf(stderr, "can't convert [%s] to ms\n", str ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: }