#include "noise.h" static unsigned lcg_seed; static float phase = 0.f; /* Augments a given signal by adding some random noise and a sinusoidal waveform */ float AddNoise(float x, float amplitude, float ratio /* 0.f-1.f */, unsigned nsamples) { float noise = .5f * (sflcg() + sflcg()); float sine = fsindeg(phase); x += amplitude * (ratio * noise + (1.f - ratio) * sine); phase += 360.f / nsamples; phase -= 360.f * ((int)phase / 360); return x; } /* Resets the sinusoidal phase and the LCG */ void ResetNoise() { slcg(0xBAADF00D); phase = 0.f; } /* Initializes the LCG */ void slcg(unsigned seed) { lcg_seed = seed; } /* [0,32767] Linear congruential generator (PRNG) */ unsigned lcg() { lcg_seed = lcg_seed * 0x343FD + 0x269EC3; return (lcg_seed >> 16) & 0x7FFF; } /* [0,1] LCG */ float flcg() { return (float)lcg() / 0x7FFF; } /* [-1,1] LCG */ float sflcg() { return 2.f * flcg() - 1.f; } /* Bhaskara sine approximation (in deg) */ float fsindeg(float x) { float t, s = 1.f; if (x < 0.f) { s = -s; x = -x; } x -= 360.f * ((int)x / 360); if (x > 180.f) { s = -s; x -= 180.f; } t = x * (180.f - x); return (4.f * s * t) / (40500.f - t); } /* Bhaskara cosine approximation (in deg) */ float fcosdeg(float x) { return fsindeg(x + 90.f); }