61 #define PINK_MAX_RANDOM_ROWS (30)
62 #define PINK_RANDOM_BITS (24)
63 #define PINK_RANDOM_SHIFT ((sizeof(long)*8)-PINK_RANDOM_BITS)
67 long pink_Rows[PINK_MAX_RANDOM_ROWS];
76 static unsigned long GenerateRandomNumber(
void );
77 void InitializePinkNoise(
PinkNoise *pink,
int numRows );
78 float GeneratePinkNoise(
PinkNoise *pink );
82 static unsigned long GenerateRandomNumber(
void )
85 static unsigned long randSeed = 22222;
86 randSeed = (randSeed * 196314165) + 907633515;
92 void InitializePinkNoise(
PinkNoise *pink,
int numRows )
97 pink->pink_IndexMask = (1<<numRows) - 1;
99 pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1));
100 pink->pink_Scalar = 1.0f / pmax;
102 for( i=0; i<numRows; i++ ) pink->pink_Rows[i] = 0;
103 pink->pink_RunningSum = 0;
108 float pinkMax = -999.0;
109 float pinkMin = 999.0;
113 float GeneratePinkNoise(
PinkNoise *pink )
119 pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask;
121 if( pink->pink_Index != 0 )
126 int n = pink->pink_Index;
127 while( (n & 1) == 0 )
136 pink->pink_RunningSum -= pink->pink_Rows[numZeros];
137 newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
138 pink->pink_RunningSum += newRandom;
139 pink->pink_Rows[numZeros] = newRandom;
143 newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
144 sum = pink->pink_RunningSum + newRandom;
146 output = pink->pink_Scalar * sum;
149 if( output > pinkMax ) pinkMax = output;
150 else if( output < pinkMin ) pinkMin = output;
164 unsigned int sampsToGo;
172 static int patestCallback(
const void* inputBuffer,
174 unsigned long framesPerBuffer,
183 float *out = (
float*)outputBuffer;
187 if( data->sampsToGo < framesPerBuffer )
189 numFrames = data->sampsToGo;
194 numFrames = framesPerBuffer;
197 for( i=0; i<numFrames; i++ )
199 *out++ = GeneratePinkNoise( &data->leftPink );
200 *out++ = GeneratePinkNoise( &data->rightPink );
202 data->sampsToGo -= numFrames;
215 static const double SR = 44100.0;
216 static const int FPB = 2048;
219 InitializePinkNoise( &data.leftPink, 12 );
220 InitializePinkNoise( &data.rightPink, 16 );
226 for( i=0; i<20; i++ )
228 pink = GeneratePinkNoise( &data.leftPink );
229 printf(
"Pink = %f\n", pink );
233 data.sampsToGo = totalSamps = (int)(60.0 * SR);
235 if( err != paNoError )
goto error;
240 fprintf(stderr,
"Error: No default output device.\n");
256 if( err != paNoError )
goto error;
259 if( err != paNoError )
goto error;
261 printf(
"Stereo pink noise for one minute...\n");
264 if( err < 0 )
goto error;
267 if( err != paNoError )
goto error;
269 printf(
"Pink min = %f, max = %f\n", pinkMin, pinkMax );
275 fprintf( stderr,
"An error occurred while using the portaudio stream\n" );
276 fprintf( stderr,
"Error number: %d\n", err );
PaError Pa_Initialize(void)
PaError Pa_OpenStream(PaStream **stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData)
PaError Pa_StartStream(PaStream *stream)
void * hostApiSpecificStreamInfo
The portable PortAudio API.
PaSampleFormat sampleFormat
PaError Pa_IsStreamActive(PaStream *stream)
unsigned long PaStreamCallbackFlags
const PaDeviceInfo * Pa_GetDeviceInfo(PaDeviceIndex device)
PaDeviceIndex Pa_GetDefaultOutputDevice(void)
const char * Pa_GetErrorText(PaError errorCode)
PaError Pa_CloseStream(PaStream *stream)
PaError Pa_Terminate(void)