diff tools/ramp.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/ramp.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,162 @@
+/*
+  ramp.c    generate an exponential sawtooth waveform
+  ------    (in binary shorts or floats).
+
+    Generate samples of a sawtooth waveform at a given sample rate.
+
+    Decaying exponential:  A.exp(-t)    0<=t<=T
+    Growing exponential:   A.exp(t)    -T<=t<=0
+	  or (shifting):   A.exp(t-T)   0<=t<=T
+
+    To arrange for a decay factor to correspond to the half life, so that
+    the wave grows/decays to half the given amplitude in the given decay time,
+    the argument of the exponential must be calibrated to result in 0.5.
+    If  exp(-x) = 0.5, then we have -x = ln(0.5) = -0.693147
+    so that:  x = 0.693147
+    For a given decay factor, the damped exponential decays to half the given
+    amplitude in this time. The ramped exponential is a time-reversed damped
+    exponential.
+
+
+Examples:
+
+1. Growing exponentials
+
+ramp polarity=ramp dec=1ms | x11plot
+
+2. Decaying exponentials
+
+ramp polarity=damp dec=1ms | x11plot
+
+3. Half a cycle of an 8ms decaying exponential.
+
+ramp polarity=damp dec=1ms dur=4ms | x11plot
+
+4. Modulating a tone with a damped exponential.
+
+tone period=.5ms amp=500 type=float    > foo1
+ramp pol=damp dec=1ms amp=1 type=float > foo2
+merge op=mult type=float foo1 foo2  |  ftos | x11plot -n512
+
+5. Modulating a tone with a ramped exponential.
+
+tone period=.5ms amp=500 type=float    > foo1
+ramp pol=ramp dec=1ms amp=1 type=float > foo2
+merge op=mult type=float foo1 foo2  |  ftos | x11plot -n512
+
+6. Modulating a tone with a damped exponential, and half-wave rectifying to
+   generate damped pulses.
+
+tone period=.5ms amp=500 type=float    > foo1
+ramp pol=damp dec=1ms amp=1 type=float > foo2
+merge op=mult type=float foo1 foo2 | ftos | gate range=min-0 op=0 | x11plot -n512
+
+7. Modulating white noise with a ramped exponential.
+
+noise type=float  > foo1
+ramp pol=ramp dec=1ms amp=1 type=float > foo2
+merge op=mult type=float foo1 foo2 | ftos | x11plot -n512
+
+
+*/
+
+#include <stdio.h>
+#include <math.h>
+#include "options.h"
+#include "units.h"
+#include "strmatch.h"
+
+char applic[]  = "generate an exponential sawtooth waveform. " ;
+char usage[]   = "ramp [options]" ;
+
+static char *helpstr, *debugstr, *sampstr, *perstr, *astr, *decstr, *polstr, *dstr, *datastr ;
+
+static Options option[] = {
+    {   "help"      ,   "off"       ,  &helpstr     ,   "help"                     , DEBUG   },
+    {   "debug"     ,   "off"       ,  &debugstr    ,   "debugging switch"         , DEBUG   },
+    {   "samplerate",   "20kHz"     ,  &sampstr     ,   "samplerate "              , VAL     },
+    {   "period"    ,   "8ms"       ,  &perstr      ,   "period [s,ms,p] of ramp"  , VAL     },
+    {   "amplitude" ,   "1024"      ,  &astr        ,   "amplitude of waveform"    , VAL     },
+    {   "decay"     ,   "2ms"       ,  &decstr      ,   "half-life of ramp"        , VAL     },
+    {   "polarity"  ,   "ramp"      ,  &polstr      ,   "ramp (growing) / damp (decaying)", VAL },
+    {   "duration"  ,   "500ms"     ,  &dstr        ,   "duration of waveform"     , VAL     },
+    {   "type"      ,   "short"     ,  &datastr     ,   "o/p datatype (short/float)", VAL     },
+   ( char * ) 0 } ;
+
+
+#define DECAYFACTOR     ( 0.693147 )
+
+int     samplerate ;
+float   amplitude  ;
+int     duration   ;
+int     period     ;
+int     decay      ;
+double  decayrate  ;
+
+main(argc, argv)
+int   argc ;
+char *argv[] ;
+{
+    int    i, n, t ;
+    short  s ;
+    float  f ;
+
+    getopts( option,argc,argv ) ;
+    if ( !isoff( helpstr ) )
+	helpopts3( helpstr, argv[0], applic, usage, option ) ;
+
+    samplerate = to_Hz( sampstr, 0 ) ;
+    amplitude  = atof( astr ) ;
+    period     = (int)to_p( perstr, samplerate ) ;
+    decay      = (int)to_p( decstr, samplerate ) ;
+    duration   = to_p( dstr, samplerate )   ;
+
+/*
+    if ( decay >= period ) {
+	fprintf(stderr,"ramp: half-life period [%dp] must be less than waveform period [%dp]\n", decay, period);
+	exit( 1 ) ;
+    }
+*/
+    decayrate  = DECAYFACTOR / (double)decay ;
+
+    if ( iststr( polstr, "damped" ) ) {
+
+	/* Decaying exponential */
+
+	if ( iststr( datastr, "short" ) )
+	    for ( i=0 ; i<duration ;  )
+		for ( t=0 ; t<period && i<duration ; t++, i++ ) {
+		    s = amplitude * exp( - (double)( t * decayrate ) ) ;
+		    fwrite( &s, sizeof(short), 1, stdout ) ;
+		}
+	else if ( iststr( datastr, "float" ) )
+	    for ( i=0 ; i<duration ;  )
+		for ( t=0 ; t<period && i<duration ; t++, i++ ) {
+		    f = amplitude * exp( - (double)( t * decayrate ) ) ;
+		    fwrite( &f, sizeof(float), 1, stdout ) ;
+		}
+	else
+	    fprintf(stderr,"unknown datatype [%s]\n", datastr) ;
+    }
+    else if ( iststr( polstr, "ramped" ) ) {
+
+	/* Growing exponential */
+
+	if ( iststr( datastr, "short" ) )
+	    for ( i=0 ; i<duration ;  )
+		for ( t=(-period) ; t<=0 && i<duration ; t++, i++ ) {
+		    s = amplitude * exp( (double)( t * decayrate ) ) ;
+		    fwrite( &s, sizeof(short), 1, stdout ) ;
+		}
+	else if ( iststr( datastr, "float" ) )
+	    for ( i=0 ; i<duration ;  )
+		for ( t=(-period) ; t<=0 && i<duration ; t++, i++ ) {
+		    f = amplitude * exp( (double)( t * decayrate ) ) ;
+		    fwrite( &f, sizeof(float), 1, stdout ) ;
+		}
+	else
+	    fprintf(stderr,"unknown datatype [%s]\n", datastr) ;
+    }
+    else
+	fprintf( stderr, "unknown polarity [%s]\n", polstr ) ;
+}