1*638691a0SAndroid Build Coastguard Worker #include <math.h>
2*638691a0SAndroid Build Coastguard Worker #include <stdlib.h>
3*638691a0SAndroid Build Coastguard Worker #include "fec.h"
4*638691a0SAndroid Build Coastguard Worker
5*638691a0SAndroid Build Coastguard Worker #define MAX_RANDOM 0x7fffffff
6*638691a0SAndroid Build Coastguard Worker
7*638691a0SAndroid Build Coastguard Worker /* Generate gaussian random double with specified mean and std_dev */
normal_rand(double mean,double std_dev)8*638691a0SAndroid Build Coastguard Worker double normal_rand(double mean, double std_dev)
9*638691a0SAndroid Build Coastguard Worker {
10*638691a0SAndroid Build Coastguard Worker double fac,rsq,v1,v2;
11*638691a0SAndroid Build Coastguard Worker static double gset;
12*638691a0SAndroid Build Coastguard Worker static int iset;
13*638691a0SAndroid Build Coastguard Worker
14*638691a0SAndroid Build Coastguard Worker if(iset){
15*638691a0SAndroid Build Coastguard Worker /* Already got one */
16*638691a0SAndroid Build Coastguard Worker iset = 0;
17*638691a0SAndroid Build Coastguard Worker return mean + std_dev*gset;
18*638691a0SAndroid Build Coastguard Worker }
19*638691a0SAndroid Build Coastguard Worker /* Generate two evenly distributed numbers between -1 and +1
20*638691a0SAndroid Build Coastguard Worker * that are inside the unit circle
21*638691a0SAndroid Build Coastguard Worker */
22*638691a0SAndroid Build Coastguard Worker do {
23*638691a0SAndroid Build Coastguard Worker v1 = 2.0 * (double)random() / MAX_RANDOM - 1;
24*638691a0SAndroid Build Coastguard Worker v2 = 2.0 * (double)random() / MAX_RANDOM - 1;
25*638691a0SAndroid Build Coastguard Worker rsq = v1*v1 + v2*v2;
26*638691a0SAndroid Build Coastguard Worker } while(rsq >= 1.0 || rsq == 0.0);
27*638691a0SAndroid Build Coastguard Worker fac = sqrt(-2.0*log(rsq)/rsq);
28*638691a0SAndroid Build Coastguard Worker gset = v1*fac;
29*638691a0SAndroid Build Coastguard Worker iset++;
30*638691a0SAndroid Build Coastguard Worker return mean + std_dev*v2*fac;
31*638691a0SAndroid Build Coastguard Worker }
32*638691a0SAndroid Build Coastguard Worker
addnoise(int sym,double amp,double gain,double offset,int clip)33*638691a0SAndroid Build Coastguard Worker unsigned char addnoise(int sym,double amp,double gain,double offset,int clip){
34*638691a0SAndroid Build Coastguard Worker int sample;
35*638691a0SAndroid Build Coastguard Worker
36*638691a0SAndroid Build Coastguard Worker sample = offset + gain*normal_rand(sym?amp:-amp,1.0);
37*638691a0SAndroid Build Coastguard Worker /* Clip to 8-bit offset range */
38*638691a0SAndroid Build Coastguard Worker if(sample < 0)
39*638691a0SAndroid Build Coastguard Worker sample = 0;
40*638691a0SAndroid Build Coastguard Worker else if(sample > clip)
41*638691a0SAndroid Build Coastguard Worker sample = clip;
42*638691a0SAndroid Build Coastguard Worker return sample;
43*638691a0SAndroid Build Coastguard Worker }
44