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