tomwalters@0: /* tomwalters@0: tone.c generate a pure tone. tomwalters@0: ------ tomwalters@0: Generate samples of a sine wave at a given sample rate. tomwalters@0: Specify wave amplitude, and frequency (in Hz or kHz), or alternatively tomwalters@0: period (in s, ms, or p (sample points) ). If both period and frequency tomwalters@0: are specified, then the given period takes precedence. tomwalters@0: If S is the samplerate, and Ts=1/S is the sample interval, tomwalters@0: then each sample of a sine wave of period T samples is given by: tomwalters@0: sin(n*(Ts/T)*TWOPI) for n=0,1,2,... tomwalters@0: Output samples in the given datatype for the given waveform duration. tomwalters@0: tomwalters@0: tomwalters@0: Examples: tomwalters@0: tomwalters@0: 1. Sine wave with period 10ms sampled at 10kHz, (100 sample points per period) tomwalters@0: tomwalters@0: tone period=10ms samplerate=10kHz | x11plot tomwalters@0: tomwalters@0: 2. Sine wave with frequency 100Hz sampled at 20kHz tomwalters@0: tomwalters@0: tone frequency=100Hz | x11plot tomwalters@0: tomwalters@0: 3. Sine wave with period 100 sample points, with dc-offset set equal to tomwalters@0: amplitude of 500 so that waveform is just non-negative. tomwalters@0: tomwalters@0: tone period=100p amplitude=500 offset=500 | x11plot tomwalters@0: tomwalters@0: 4. Quarter cycle of a sine wave with 8ms period. tomwalters@0: tomwalters@0: tone period=8ms duration=2ms | x11plot tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include "options.h" tomwalters@0: #include "units.h" tomwalters@0: #include "strmatch.h" tomwalters@0: tomwalters@0: #define TWOPI 6.28318530717 tomwalters@0: tomwalters@0: char applic[] = "generate a pure tone. " ; tomwalters@0: char usage[] = "tone [options]" ; tomwalters@0: tomwalters@0: static char *helpstr, *debugstr, *sampstr, *perstr, *freqstr, *astr, *ostr, *dstr, *typestr ; tomwalters@0: static char *phasestr ; tomwalters@0: tomwalters@0: static Options option[] = { tomwalters@0: { "help" , "off" , &helpstr , "help" , DEBUG }, tomwalters@0: { "debug" , "off" , &debugstr , "debugging switch" , DEBUG }, tomwalters@0: { "samplerate", "20kHz" , &sampstr , "samplerate " , VAL }, tomwalters@0: { "period" , "8ms" , &perstr , "period of waveform" , VAL }, tomwalters@0: { "frequency" , "125Hz" , &freqstr , "frequency of waveform" , VAL }, tomwalters@0: { "phase" , "0" , &phasestr , "phase offset" , VAL }, tomwalters@0: { "amplitude" , "512" , &astr , "amplitude of waveform" , VAL }, tomwalters@0: { "mean" , "0" , &ostr , "mean value of waveform" , VAL }, tomwalters@0: { "duration" , "500ms" , &dstr , "duration of waveform" , VAL }, tomwalters@0: { "type" , "short" , &typestr , "output datatype" , VAL }, tomwalters@0: ( char * ) 0 } ; tomwalters@0: tomwalters@0: tomwalters@0: int samplerate ; tomwalters@0: float amplitude ; tomwalters@0: float offset ; tomwalters@0: int type ; /* datatype index */ tomwalters@0: tomwalters@0: main(argc, argv) tomwalters@0: int argc ; tomwalters@0: char *argv[] ; tomwalters@0: { tomwalters@0: float T=0, Tr, r, y ; tomwalters@0: int i, n ; tomwalters@0: tomwalters@0: getopts( option,argc,argv ) ; tomwalters@0: if ( !isoff( helpstr ) ) tomwalters@0: helpopts3( helpstr, argv[0], applic, usage, option ) ; tomwalters@0: tomwalters@0: samplerate = to_Hz( sampstr, 0 ) ; tomwalters@0: amplitude = atof( astr ) ; tomwalters@0: offset = atof( ostr ) ; tomwalters@0: tomwalters@0: if ( ( type = typeindex( typestr ) ) < 0 ) { tomwalters@0: fprintf( stderr, "tone: bad type [%s]\n", typestr ) ; tomwalters@0: exit( 1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: n = to_p( dstr, samplerate ) ; tomwalters@0: tomwalters@0: if ( isstr( perstr, optdflt( option, "period" ) ) ) tomwalters@0: T = 1.0 / to_Hz( freqstr, samplerate ) ; tomwalters@0: else tomwalters@0: T = to_s( perstr, samplerate ) ; tomwalters@0: tomwalters@0: Tr = TWOPI / ( samplerate * T ) ; /* period of max resolution */ tomwalters@0: tomwalters@0: if ( iststr( phasestr, "sine" ) ) /* start */ tomwalters@0: r = 0 ; tomwalters@0: else if ( iststr( phasestr, "cosine" ) ) tomwalters@0: r = TWOPI / 4 ; tomwalters@0: else if ( iststr( phasestr, "antisine" ) ) tomwalters@0: r = TWOPI / 2 ; tomwalters@0: else if ( iststr( phasestr, "anticosine" ) ) tomwalters@0: r = 3 * TWOPI / 4 ; tomwalters@0: else if ( isstr( phasestr + strlen( phasestr ) - 3, "deg" ) ) tomwalters@0: r = TWOPI * ( atof( phasestr ) / 360. ) ; tomwalters@0: else tomwalters@0: r = TWOPI * ( to_s( phasestr, samplerate ) / T ) ; tomwalters@0: tomwalters@0: for ( i = 0 ; i < n ; i++, r += Tr ) { tomwalters@0: y = amplitude * sin(r) + offset ; tomwalters@0: writeitem( &y, type, 1, stdout ) ; tomwalters@0: } tomwalters@0: }