view 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 source
/*
  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 ) ;
}