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 ) ;
+    }
+}