annotate tools/noise.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
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 noise.c generate samples of a normally distributed deviate (white noise)
tomwalters@0 3 ------- in binary shorts or floats.
tomwalters@0 4
tomwalters@0 5
tomwalters@0 6 The routine gasdev returns normally distributed numbers with zero mean
tomwalters@0 7 and unit variance, using the Box-Muller method described in Numerical
tomwalters@0 8 recipes [p203]. It is based upon a random number generator ran1 which
tomwalters@0 9 generates uniformly distributed numbers in the range [0,1].
tomwalters@0 10
tomwalters@0 11 The period of the random sequences is claimed to be infinite,
tomwalters@0 12 [Numerical recipes, p196].
tomwalters@0 13 Random sequences which repeat can be heard as periodic if the sequence
tomwalters@0 14 repeats every 4secs or less. Therefore the period of a random sequence
tomwalters@0 15 should be greater than 5secs, or 100000 samples (at 20kHz samplerate).
tomwalters@0 16
tomwalters@0 17 The seed of each random sequence is the variable "seed", which should be
tomwalters@0 18 set to any negative value to initialize or re-initialize the sequence,
tomwalters@0 19 [Numerical recipes, p196]. The same seed gives the same random sequence.
tomwalters@0 20 Otherwise, (and by default when seed=off or seed=0), the system call
tomwalters@0 21 getpid() supplies a new seed each run.
tomwalters@0 22
tomwalters@0 23 Each sample is scaled using the given mean and variance parameters so that
tomwalters@0 24 samples are drawn from a normal distribution of given mean and variance.
tomwalters@0 25 */
tomwalters@0 26
tomwalters@0 27
tomwalters@0 28 #include <stdio.h>
tomwalters@0 29 #include <math.h>
tomwalters@0 30 #include "options.h"
tomwalters@0 31 #include "units.h"
tomwalters@0 32 #include "strmatch.h"
tomwalters@0 33
tomwalters@0 34 char applic[] = "generate white noise. " ;
tomwalters@0 35 char usage[] = "noise [options]" ;
tomwalters@0 36
tomwalters@0 37 static char *helpstr, *debugstr, *sampstr, *durstr, *meanstr, *varstr, *seedstr, *datastr ;
tomwalters@0 38
tomwalters@0 39 static Options option[] = {
tomwalters@0 40 { "help" , "off" , &helpstr , "help" , DEBUG },
tomwalters@0 41 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
tomwalters@0 42 { "samplerate", "20kHz" , &sampstr , "samplerate " , VAL },
tomwalters@0 43 { "duration" , "500ms" , &durstr , "duration of waveform" , VAL },
tomwalters@0 44 { "mean" , "0" , &meanstr , "mean value of waveform" , VAL },
tomwalters@0 45 { "variance" , "500" , &varstr , "variance of values" , VAL },
tomwalters@0 46 { "seed" , "off" , &seedstr , "seed for random sequence" , VAL },
tomwalters@0 47 { "type" , "short" , &datastr , "o/p datatype (short/float)", VAL },
tomwalters@0 48 ( char * ) 0 } ;
tomwalters@0 49
tomwalters@0 50
tomwalters@0 51 int samplerate ;
tomwalters@0 52 int duration ;
tomwalters@0 53 float mean ;
tomwalters@0 54 float variance ;
tomwalters@0 55 int seed ;
tomwalters@0 56
tomwalters@0 57
tomwalters@0 58 main (argc,argv)
tomwalters@0 59 int argc;
tomwalters@0 60 char **argv;
tomwalters@0 61 {
tomwalters@0 62 float gasdev();
tomwalters@0 63 float n2 ;
tomwalters@0 64 short n1 ;
tomwalters@0 65
tomwalters@0 66 getopts( option,argc,argv ) ;
tomwalters@0 67 if ( !isoff( helpstr ) )
tomwalters@0 68 helpopts3( helpstr, argv[0], applic, usage, option ) ;
tomwalters@0 69
tomwalters@0 70 samplerate = to_Hz( sampstr, 0 ) ;
tomwalters@0 71 duration = to_p( durstr, samplerate ) ;
tomwalters@0 72 mean = atof( meanstr ) ;
tomwalters@0 73 variance = atof( varstr ) ;
tomwalters@0 74
tomwalters@0 75 if ( isoff( seedstr ) )
tomwalters@0 76 seed = ( -getpid() ) ;
tomwalters@0 77 else
tomwalters@0 78 seed = atoi( seedstr ) ;
tomwalters@0 79
tomwalters@0 80
tomwalters@0 81 if ( iststr( datastr, "short" ) )
tomwalters@0 82 while ( duration-- ) {
tomwalters@0 83 n1 = (short)( gasdev( &seed ) * variance + mean ) ;
tomwalters@0 84 fwrite( &n1, sizeof(short), 1, stdout ) ;
tomwalters@0 85 }
tomwalters@0 86
tomwalters@0 87 else if ( iststr( datastr, "float" ) )
tomwalters@0 88 while ( duration-- ) {
tomwalters@0 89 n2 = gasdev( &seed ) * variance + mean ;
tomwalters@0 90 fwrite( &n2, sizeof(float), 1, stdout ) ;
tomwalters@0 91 }
tomwalters@0 92
tomwalters@0 93 else
tomwalters@0 94 fprintf(stderr,"noise: unknown datatype [%s]\n", datastr) ;
tomwalters@0 95 }
tomwalters@0 96
tomwalters@0 97
tomwalters@0 98 float gasdev( idum )
tomwalters@0 99 int *idum;
tomwalters@0 100 {
tomwalters@0 101 static int iset=0;
tomwalters@0 102 static float gset;
tomwalters@0 103 float fac,r,v1,v2;
tomwalters@0 104 float ran1();
tomwalters@0 105
tomwalters@0 106 if ( iset == 0 ) {
tomwalters@0 107 do {
tomwalters@0 108 v1 = 2.0 * ran1( idum ) - 1.0 ;
tomwalters@0 109 v2 = 2.0 * ran1( idum ) - 1.0 ;
tomwalters@0 110 r = v1*v1+v2*v2;
tomwalters@0 111 } while (r >= 1.0);
tomwalters@0 112 fac = sqrt(-2.0*log(r)/r);
tomwalters@0 113 gset = v1*fac;
tomwalters@0 114 iset = 1;
tomwalters@0 115 return v2*fac;
tomwalters@0 116 }
tomwalters@0 117 else {
tomwalters@0 118 iset = 0;
tomwalters@0 119 return gset;
tomwalters@0 120 }
tomwalters@0 121 }
tomwalters@0 122
tomwalters@0 123
tomwalters@0 124 #define M1 259200
tomwalters@0 125 #define IA1 7141
tomwalters@0 126 #define IC1 54773
tomwalters@0 127 #define RM1 (1.0/M1)
tomwalters@0 128 #define M2 134456
tomwalters@0 129 #define IA2 8121
tomwalters@0 130 #define IC2 28411
tomwalters@0 131 #define RM2 (1.0/M2)
tomwalters@0 132 #define M3 243000
tomwalters@0 133 #define IA3 4561
tomwalters@0 134 #define IC3 51349
tomwalters@0 135
tomwalters@0 136 float ran1( idum )
tomwalters@0 137 int *idum;
tomwalters@0 138 {
tomwalters@0 139 static long ix1,ix2,ix3;
tomwalters@0 140 static float r[98];
tomwalters@0 141 float temp;
tomwalters@0 142 static int iff=0;
tomwalters@0 143 int j;
tomwalters@0 144
tomwalters@0 145 if ( *idum < 0 || iff == 0 ) {
tomwalters@0 146 iff=1;
tomwalters@0 147 ix1=(IC1-(*idum)) % M1;
tomwalters@0 148 ix1=(IA1*ix1+IC1) % M1;
tomwalters@0 149 ix2=ix1 % M2;
tomwalters@0 150 ix1=(IA1*ix1+IC1) % M1;
tomwalters@0 151 ix3=ix1 % M3;
tomwalters@0 152 for (j=1;j<=97;j++) {
tomwalters@0 153 ix1=(IA1*ix1+IC1) % M1;
tomwalters@0 154 ix2=(IA2*ix2+IC2) % M2;
tomwalters@0 155 r[j]=(ix1+ix2*RM2)*RM1;
tomwalters@0 156 }
tomwalters@0 157 *idum=1;
tomwalters@0 158 }
tomwalters@0 159 ix1=(IA1*ix1+IC1) % M1;
tomwalters@0 160 ix2=(IA2*ix2+IC2) % M2;
tomwalters@0 161 ix3=(IA3*ix3+IC3) % M3;
tomwalters@0 162 j=1 + ((97*ix3)/M3);
tomwalters@0 163 if (j > 97 || j < 1) {
tomwalters@0 164 fprintf(stderr, "noise: This cannot happen\n");
tomwalters@0 165 exit(1);
tomwalters@0 166 }
tomwalters@0 167 temp=r[j];
tomwalters@0 168 r[j]=(ix1+ix2*RM2)*RM1;
tomwalters@0 169 return temp;
tomwalters@0 170 }
tomwalters@0 171