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