Files
JaySynth/Source/synth/noise.c
T
jens 843c6e300c - initial import
git-svn-id: http://moon:8086/svn/software/trunk/projects/JaySynth@37 b431acfa-c32f-4a4a-93f1-934dc6c82436
2014-10-25 07:27:55 +00:00

95 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// --------------------------------------------------------------
// --------------------------------------------------------------
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "synth_defs.h"
#include "noise.h"
// --------------------------------------------------------------
// internal funcs
// --------------------------------------------------------------
#define PM_IA 16807
#define PM_IM 2147483647
#define PM_AM (1.0/PM_IM)
#define PM_IQ 127773
#define PM_IR 2836
#define PM_MASK 123459876
// 'Minimal' random number generator of Park and Miller. Returns a uniform random deviate
// between 0.0 and 1.0. Set or resetidumto any integer value (except the unlikely value MASK)
// to initialize the sequence; idummust not be altered between calls for successive deviates in
// a sequence.
double ran0(long *idum)
{
long k;
double ans;
*idum ^= PM_MASK; // XORing with MASKallows use of zero and other
k=(*idum)/PM_IQ; // simple bit patterns for idum.
*idum=PM_IA*(*idum-k*PM_IQ)-PM_IR *k; // Compute idum=(IA*idum) % IM without over-
// flows by Schrages method.
if (*idum < 0)
*idum += PM_IM;
ans=PM_AM*(*idum); // Convert idumto a floating result.
*idum ^= PM_MASK; // Unmask before return.
return ans;
}
// --------------------------------------------------------------
// Exported functions
// --------------------------------------------------------------
void Noise_Init(noise_gen_t *pObj, UINT32 seed)
{
pObj->state = (long)(seed & NOISE_LFSR_MAX);
}
void Noise_Free(noise_gen_t *pObj)
{
}
synth_float_t Noise_Uniform(noise_gen_t *pObj, synth_float_t var, synth_float_t mu)
{
/*
if (pObj->lfsr & 0x800000)
pObj->lfsr = ((pObj->lfsr << 1) | 1) ^ NOISE_LFSR_POLY;
else
pObj->lfsr = (pObj->lfsr << 1);
pObj->lfsr &= NOISE_LFSR_MAX;
*/
/* taps: 32 31 29 1; characteristic polynomial: x^32 + x^31 + x^29 + x + 1 */
// pObj->lfsr = (pObj->lfsr >> 1) ^ (-(pObj->lfsr & 1) & NOISE_LFSR_POLY);
// return var * ((synth_float_t)rand()/(RAND_MAX+1) + mu -0.5);
return var*(ran0(&pObj->state) + mu -0.5);
}
synth_float_t Noise_Gaussian(noise_gen_t *pObj, synth_float_t std, synth_float_t mu)
{
synth_float_t U1, U2, V1, V2, S, Y;
do
{
U1 = Noise_Uniform(pObj, 1, 0.5); // U1=[0,1]
U2 = Noise_Uniform(pObj, 1, 0.5); // U2=[0,1]
V1 = 2 * U1 - 1; // V1=[-1,1]
V2 = 2 * U2 - 1; // V2=[-1,1]
S = V1 * V1 + V2 * V2;
} while (S >= 1);
// X = sqrt(-2 * log(S) / S) * V1;
Y = sqrt(-2 * log(S) / S) * V2;
Y = mu + std*Y;
return Y;
}