|
MythTV
0.26-pre
|
00001 /* 00002 patest_pink.c 00003 00004 generate Pink Noise using Gardner method. 00005 Optimization suggested by James McCartney uses a tree 00006 to select which random value to replace. 00007 00008 x x x x x x x x x x x x x x x x 00009 x x x x x x x x 00010 x x x x 00011 x x 00012 x 00013 00014 Tree is generated by counting trailing zeros in an increasing index. 00015 When the index is zero, no random number is selected. 00016 00017 This program uses the Portable Audio library which is under development. 00018 For more information see: http://www.audiomulch.com/portaudio/ 00019 00020 Author: Phil Burk, http://www.softsynth.com 00021 00022 Revision History: 00023 00024 Copyleft 1999 Phil Burk - No rights reserved. 00025 */ 00026 00027 #include <stdio.h> 00028 #include <math.h> 00029 #include "pink.h" 00030 00031 /************************************************************/ 00032 /* Calculate pseudo-random 32 bit number based on linear congruential method. */ 00033 static unsigned long generate_random_number( void ) 00034 { 00035 static unsigned long rand_seed = 22222; /* Change this for different random sequences. */ 00036 rand_seed = (rand_seed * 196314165) + 907633515; 00037 return rand_seed; 00038 } 00039 00040 /* Setup PinkNoise structure for N rows of generators. */ 00041 void initialize_pink_noise( pink_noise_t *pink, int num_rows ) 00042 { 00043 int i; 00044 long pmax; 00045 pink->pink_index = 0; 00046 pink->pink_index_mask = (1<<num_rows) - 1; 00047 /* Calculate maximum possible signed random value. Extra 1 for white noise always added. */ 00048 pmax = (num_rows + 1) * (1<<(PINK_RANDOM_BITS-1)); 00049 pink->pink_scalar = 1.0f / pmax; 00050 /* Initialize rows. */ 00051 for( i=0; i<num_rows; i++ ) pink->pink_rows[i] = 0; 00052 pink->pink_running_sum = 0; 00053 } 00054 00055 /* generate Pink noise values between -1.0 and +1.0 */ 00056 float generate_pink_noise_sample( pink_noise_t *pink ) 00057 { 00058 long new_random; 00059 long sum; 00060 float output; 00061 00062 /* Increment and mask index. */ 00063 pink->pink_index = (pink->pink_index + 1) & pink->pink_index_mask; 00064 00065 /* If index is zero, don't update any random values. */ 00066 if( pink->pink_index != 0 ) 00067 { 00068 /* Determine how many trailing zeros in PinkIndex. */ 00069 /* This algorithm will hang if n==0 so test first. */ 00070 int num_zeros = 0; 00071 int n = pink->pink_index; 00072 while( (n & 1) == 0 ) 00073 { 00074 n = n >> 1; 00075 num_zeros++; 00076 } 00077 00078 /* Replace the indexed ROWS random value. 00079 * Subtract and add back to Running_sum instead of adding all the random 00080 * values together. Only one changes each time. 00081 */ 00082 pink->pink_running_sum -= pink->pink_rows[num_zeros]; 00083 new_random = ((long)generate_random_number()) >> PINK_RANDOM_SHIFT; 00084 pink->pink_running_sum += new_random; 00085 pink->pink_rows[num_zeros] = new_random; 00086 } 00087 00088 /* Add extra white noise value. */ 00089 new_random = ((long)generate_random_number()) >> PINK_RANDOM_SHIFT; 00090 sum = pink->pink_running_sum + new_random; 00091 00092 /* Scale to range of -1.0 to 0.9999. */ 00093 output = pink->pink_scalar * sum; 00094 00095 return output; 00096 }
1.7.6.1