Skip to content

Commit

Permalink
Rand: Replacing rand() for portable tests
Browse files Browse the repository at this point in the history
In order to keep tests simple with respect to signal processing code, a portable
Pseudo Random Number Generator was built.
This will ensure that the sequence of random numbers from a given seed are
identical from platform to platform.
As this is not a cryptographic application, this behavior should not be an
issue.
Basic statistics of random source verified.

For source of magic numbers, see glibc.
  • Loading branch information
fundamental committed Sep 13, 2011
1 parent d44dc9b commit 604c9ef
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/DSP/Unison.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#ifndef UNISON_H
#define UNISON_H
#include <stdlib.h>
#include "../globals.h"
#include "../Misc/Util.h"

#define UNISON_FREQ_SPAN 2.0f
//how much the unison frequencies varies (always >= 1.0f)
Expand Down
6 changes: 3 additions & 3 deletions src/Effects/EffectLFO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
*/

#include <cstdlib>
#include <cmath>

#include "EffectLFO.h"
#include "../Misc/Util.h"

#include <cstdlib>
#include <cmath>

EffectLFO::EffectLFO()
{
Expand Down
5 changes: 3 additions & 2 deletions src/Misc/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@
#include <sched.h>


int SAMPLE_RATE = 44100;
int SAMPLE_RATE = 44100;
int SOUND_BUFFER_SIZE = 256;
int OSCIL_SIZE = 1024;
int OSCIL_SIZE = 1024;
prng_t prng_state = 0x1234;

Config config;
float *denormalkillbuf;
Expand Down
28 changes: 28 additions & 0 deletions src/Misc/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <string>
#include <sstream>
#include <stdint.h>
#include "Config.h"
#include "../globals.h"

Expand Down Expand Up @@ -86,6 +87,33 @@ T limit(T val, T min, T max)
return (val < min ? min : (val > max ? max : val));
}

//Random number generator

typedef uint32_t prng_t;
extern prng_t prng_state;

// Portable Pseudo-Random Number Generator
inline prng_t prng_r(prng_t &p)
{
return (p = p * 1103515245 + 12345);
}

inline prng_t prng(void)
{
return prng_r(prng_state)&0x7fffffff;
}

inline void sprng(prng_t p)
{
prng_state = p;
}

/*
* The random generator (0.0f..1.0f)
*/
# define INT32_MAX (2147483647)
#define RND (prng() / (INT32_MAX * 1.0f))


#endif

5 changes: 3 additions & 2 deletions src/Output/DSSIaudiooutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
//this file contains code used from trivial_synth.c from
//the DSSI (published by Steve Harris under public domain) as a template.

#include <string.h>
#include "DSSIaudiooutput.h"
#include "../Misc/Config.h"
#include "../Misc/Bank.h"
#include "../Misc/Util.h"
#include <string.h>
#include <limits.h>

using std::string;
Expand Down Expand Up @@ -603,7 +604,7 @@ DSSIaudiooutput::DSSIaudiooutput(unsigned long sampleRate)

config.init();

srand(time(NULL));
sprng(time(NULL));
denormalkillbuf=new float [SOUND_BUFFER_SIZE];
for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=(RND-0.5f)*1e-16;

Expand Down
3 changes: 2 additions & 1 deletion src/Params/FilterParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
*/

#include "FilterParams.h"
#include "../Misc/Util.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "FilterParams.h"

FilterParams::FilterParams(unsigned char Ptype_,
unsigned char Pfreq_,
Expand Down
14 changes: 7 additions & 7 deletions src/Synth/ADnote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ ADnote::ADnote(ADnoteParameters *pars,
NoteGlobalPar.Punch.Enabled = 0;

for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
pars->VoicePar[nvoice].OscilSmp->newrandseed(rand());
pars->VoicePar[nvoice].OscilSmp->newrandseed(prng());
NoteVoicePar[nvoice].OscilSmp = NULL;
NoteVoicePar[nvoice].FMSmp = NULL;
NoteVoicePar[nvoice].VoiceOut = NULL;
Expand Down Expand Up @@ -275,7 +275,7 @@ ADnote::ADnote(ADnoteParameters *pars,
if(pars->VoicePar[nvoice].Pextoscil != -1)
vc = pars->VoicePar[nvoice].Pextoscil;
if(!pars->GlobalPar.Hrandgrouping)
pars->VoicePar[vc].OscilSmp->newrandseed(rand());
pars->VoicePar[vc].OscilSmp->newrandseed(prng());
int oscposhi_start =
pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,
getvoicebasefreq(nvoice),
Expand Down Expand Up @@ -478,7 +478,7 @@ void ADnote::legatonote(float freq, float velocity, int portamento_,
if(pars->VoicePar[nvoice].Pextoscil != -1)
vc = pars->VoicePar[nvoice].Pextoscil;
if(!pars->GlobalPar.Hrandgrouping)
pars->VoicePar[vc].OscilSmp->newrandseed(rand());
pars->VoicePar[vc].OscilSmp->newrandseed(prng());

pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,
getvoicebasefreq(nvoice),
Expand Down Expand Up @@ -605,7 +605,7 @@ void ADnote::legatonote(float freq, float velocity, int portamento_,
/* Voice Modulation Parameters Init */
if((NoteVoicePar[nvoice].FMEnabled != NONE)
&& (NoteVoicePar[nvoice].FMVoice < 0)) {
partparams->VoicePar[nvoice].FMSmp->newrandseed(rand());
partparams->VoicePar[nvoice].FMSmp->newrandseed(prng());

//Perform Anti-aliasing only on MORPH or RING MODULATION

Expand All @@ -614,7 +614,7 @@ void ADnote::legatonote(float freq, float velocity, int portamento_,
vc = partparams->VoicePar[nvoice].PextFMoscil;

if(!partparams->GlobalPar.Hrandgrouping)
partparams->VoicePar[vc].FMSmp->newrandseed(rand());
partparams->VoicePar[vc].FMSmp->newrandseed(prng());

for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE + i] =
Expand Down Expand Up @@ -777,7 +777,7 @@ void ADnote::initparameters()

/* Voice Modulation Parameters Init */
if((vce.FMEnabled != NONE) && (vce.FMVoice < 0)) {
param.FMSmp->newrandseed(rand());
param.FMSmp->newrandseed(prng());
vce.FMSmp = new float[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES];

//Perform Anti-aliasing only on MORPH or RING MODULATION
Expand All @@ -793,7 +793,7 @@ void ADnote::initparameters()
tmp = getFMvoicebasefreq(nvoice);

if(!partparams->GlobalPar.Hrandgrouping)
partparams->VoicePar[vc].FMSmp->newrandseed(rand());
partparams->VoicePar[vc].FMSmp->newrandseed(prng());

for(int k = 0; k < unison_size[nvoice]; ++k)
oscposhiFM[nvoice][k] = (oscposhi[nvoice][k]
Expand Down
6 changes: 3 additions & 3 deletions src/Synth/LFO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
*/

#include "LFO.h"
#include "../Misc/Util.h"

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "LFO.h"


LFO::LFO(LFOParams *lfopars, float basefreq)
{
if(lfopars->Pstretch == 0)
Expand Down
6 changes: 3 additions & 3 deletions src/Synth/OscilGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,8 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)

//Harmonic Amplitude Randomness
if((freqHz > 0.1f) && (!ADvsPAD)) {
unsigned int realrnd = rand();
srand(randseed);
unsigned int realrnd = prng();
sprng(randseed);
float power = Pamprandpower / 127.0f;
float normalize = 1.0f / (1.2f - power);
switch(Pamprandtype) {
Expand All @@ -872,7 +872,7 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)
* normalize;
break;
}
srand(realrnd + 1);
sprng(realrnd + 1);
}

if((freqHz > 0.1f) && (resonance != 0))
Expand Down
10 changes: 5 additions & 5 deletions src/Tests/AdNoteTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,26 +118,26 @@ class AdNoteTest:public CxxTest::TestSuite
#endif
sampleCount += SOUND_BUFFER_SIZE;

TS_ASSERT_DELTA(outL[255], 0.3019f, 0.0001f);
TS_ASSERT_DELTA(outL[255], 0.254609f, 0.0001f);

note->relasekey();


note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], -0.1382f, 0.0001f);
TS_ASSERT_DELTA(outL[255], -0.102197f, 0.0001f);

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], -0.0334f, 0.0001f);
TS_ASSERT_DELTA(outL[255], -0.111422f, 0.0001f);

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], -0.1329f, 0.0001f);
TS_ASSERT_DELTA(outL[255], -0.021375f, 0.0001f);

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], 0.2690f, 0.0001f);
TS_ASSERT_DELTA(outL[255], 0.149882f, 0.0001f);

while(!note->finished()) {
note->noteout(outL, outR);
Expand Down
1 change: 1 addition & 0 deletions src/Tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ target_link_libraries(EchoTest ${test_lib})
target_link_libraries(MicrotonalTest ${test_lib})
target_link_libraries(OscilGenTest ${test_lib})
target_link_libraries(XMLwrapperTest ${test_lib})
target_link_libraries(RandTest ${test_lib})
8 changes: 4 additions & 4 deletions src/Tests/OscilGenTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ class OscilGenTest:public CxxTest::TestSuite
void testOutput(void)
{
oscil->get(outL, freq);
TS_ASSERT_DELTA(outL[23], -0.014717f, 0.0001f);
TS_ASSERT_DELTA(outL[129], -0.567502f, 0.0001f);
TS_ASSERT_DELTA(outL[586], -0.030894f, 0.0001f);
TS_ASSERT_DELTA(outL[1023], -0.080001f, 0.0001f);
TS_ASSERT_DELTA(outL[23], -0.044547f, 0.0001f);
TS_ASSERT_DELTA(outL[129], -0.018169f, 0.0001f);
TS_ASSERT_DELTA(outL[586], 0.045647f, 0.0001f);
TS_ASSERT_DELTA(outL[1023], -0.038334f, 0.0001f);
}

void testSpectrum(void)
Expand Down
12 changes: 6 additions & 6 deletions src/Tests/RandTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/

#include "../globals.h"
#include "../Misc/Util.h"

#include <cstdlib>
#include <cstdio>
Expand All @@ -31,11 +31,11 @@ class RandTest:public CxxTest::TestSuite
public:
void testPRNG(void) {
//verify RND returns expected pattern when unseeded
TS_ASSERT_DELTA(RND, 0.840188f, 0.00001f);
TS_ASSERT_DELTA(RND, 0.394383f, 0.00001f);
TS_ASSERT_DELTA(RND, 0.783099f, 0.00001f);
TS_ASSERT_DELTA(RND, 0.798440f, 0.00001f);
TS_ASSERT_DELTA(RND, 0.911647f, 0.00001f);
TS_ASSERT_DELTA(RND, 0.607781, 0.00001);
TS_ASSERT_DELTA(RND, 0.591761, 0.00001);
TS_ASSERT_DELTA(RND, 0.186133, 0.00001);
TS_ASSERT_DELTA(RND, 0.286319, 0.00001);
TS_ASSERT_DELTA(RND, 0.511766, 0.00001);
}
};

Expand Down
8 changes: 4 additions & 4 deletions src/Tests/SubNoteTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,19 @@ class SubNoteTest:public CxxTest::TestSuite

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], 0.0022f, 0.0001f);
TS_ASSERT_DELTA(outL[255], 0.0016f, 0.0001f);

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], -0.0020f, 0.0001f);
TS_ASSERT_DELTA(outL[255], -0.0000f, 0.0001f);

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], 0.0010f, 0.0001f);
TS_ASSERT_DELTA(outL[255], -0.0013f, 0.0001f);

note->noteout(outL, outR);
sampleCount += SOUND_BUFFER_SIZE;
TS_ASSERT_DELTA(outL[255], 0.0005f, 0.0001f);
TS_ASSERT_DELTA(outL[255], -0.0002f, 0.0001f);

while(!note->finished()) {
note->noteout(outL, outR);
Expand Down
6 changes: 1 addition & 5 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#ifndef GLOBALS_H
#define GLOBALS_H
#include <stdint.h>

/**Sampling rate*/
extern int SAMPLE_RATE;
Expand Down Expand Up @@ -171,11 +172,6 @@ extern int OSCIL_SIZE;
#define dB2rap(dB) ((expf((dB) * LOG_10 / 20.0f)))
#define rap2dB(rap) ((20 * logf(rap) / LOG_10))

/*
* The random generator (0.0f..1.0f)
*/
#define RND (rand() / (RAND_MAX * 1.0f))

#define ZERO(data, size) {char *data_ = (char *) data; for(int i = 0; \
i < size; \
i++) \
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ int main(int argc, char *argv[])
OSCIL_SIZE = config.cfg.OscilSize;
swaplr = config.cfg.SwapStereo;

srand(time(NULL));
sprng(time(NULL));
//produce denormal buf
denormalkillbuf = new float [SOUND_BUFFER_SIZE];
for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
Expand Down

0 comments on commit 604c9ef

Please sign in to comment.