xref: /aosp_15_r20/external/fec/sim.c (revision 638691a093b4f9473cd6ee8f3e0139deef159a86)
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