Mercurial > hg > aim92
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 |