49 lines
1.1 KiB
C
49 lines
1.1 KiB
C
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include "fec.h"
|
|
|
|
#define MAX_RANDOM 0x7fffffff
|
|
|
|
/* Generate gaussian random double with specified mean and std_dev */
|
|
double normal_rand(double mean, double std_dev)
|
|
{
|
|
double fac, rsq, v1, v2;
|
|
static double gset;
|
|
static int iset;
|
|
|
|
if (iset) {
|
|
/* Already got one */
|
|
iset = 0;
|
|
return mean + std_dev * gset;
|
|
}
|
|
/* Generate two evenly distributed numbers between -1 and +1
|
|
* that are inside the unit circle
|
|
*/
|
|
do {
|
|
v1 = 2.0 * (double)random() / MAX_RANDOM - 1;
|
|
v2 = 2.0 * (double)random() / MAX_RANDOM - 1;
|
|
rsq = v1 * v1 + v2 * v2;
|
|
}
|
|
while (rsq >= 1.0 || rsq == 0.0);
|
|
fac = sqrt(-2.0 * log(rsq) / rsq);
|
|
gset = v1 * fac;
|
|
iset++;
|
|
return mean + std_dev * v2 * fac;
|
|
}
|
|
|
|
unsigned char addnoise(int sym, double amp, double gain, double offset,
|
|
int clip)
|
|
{
|
|
int sample;
|
|
|
|
sample = offset + gain * normal_rand(sym ? amp : -amp, 1.0);
|
|
/* Clip to 8-bit offset range */
|
|
if (sample < 0) {
|
|
sample = 0;
|
|
}
|
|
else if (sample > clip) {
|
|
sample = clip;
|
|
}
|
|
return sample;
|
|
}
|