From ec73701a0adaad26f0eee2fac8b7a1f041ba74d0 Mon Sep 17 00:00:00 2001 From: theGreatWhiteShark Date: Fri, 20 Jul 2018 22:30:13 +0200 Subject: [PATCH] Doxygen documentation for the randomizer --- src/core/include/hydrogen/randomizer.h | 76 +++++++++++--- src/core/src/randomizer.cpp | 135 ++++++++++++++++++------- 2 files changed, 158 insertions(+), 53 deletions(-) diff --git a/src/core/include/hydrogen/randomizer.h b/src/core/include/hydrogen/randomizer.h index 87a8bc2704..68db412d18 100644 --- a/src/core/include/hydrogen/randomizer.h +++ b/src/core/include/hydrogen/randomizer.h @@ -29,13 +29,37 @@ #include #define PI ( 3.1415926536d ) +/** + * Number of white noise sources to approximate a 1/f spectrum in the + * pink() function. + */ #define PINK_USED_ROWS ( 12 ) +/** + * Maximum number of independent white noise sources to be used in + * pink(). + */ #define PINK_MAX_ROWS ( 30 ) +/** + * Number of bits used in the output of the pink() function. + */ #define PINK_BITS ( 24 ) +/** + * How much bits less then the 32 bit long integer does the output of + * the pink() function have. + */ #define PINK_SHIFT ( ( sizeof( long )* 8 ) - PINK_BITS ) namespace H2Core { +/** + * @brief Used to generate all random numbers used within the humanizer. + * + * Since not only Gaussian white noise, with increments perfectly + * independent from each other, but also noise of different colors + * will be use, this object provides a state of the random number + * generator. This state is required to draw the next, correlated + * number and should not be shared between different instruments. + */ class Randomizer { public: // Constructor and destructor @@ -69,34 +93,56 @@ class Randomizer { private: static Randomizer* __instance; ////////////// White uniform noise /////////////////////////// - // Internal state of the white uniform random number - // generator. + /** + * Internal state of the white uniform random number + * generator. + */ unsigned long long int uniformStateInt64; ////////////////////////////////////////////////////////////// // ////////////////////// Gaussian white noise ////////////////// - // This methods generates two Gaussian-distributed variables - // out of two uniformly distributed ones. One will be returned - // and the other stored in this variable to be returned during - // the next call. + /** + * @brief Auxiliary variable storing an addition Gaussian + * white number. + * + * The white_gaussian() function generates two + * Gaussian-distributed variables out of two uniformly + * distributed ones. One will be returned and the other stored + * in this variable to be returned during the next call. + */ double gaussianSecondVariable; ////////////////////////////////////////////////////////////// // /////////////////////////// Pink noise /////////////////////// - // Array containing the `PINK_MAX_ROWS' independent white - // noise sources. + /** + * Array containing the PINK_MAX_ROWS independent white + * noise sources in the pink() function. + */ long rowsPink[ PINK_MAX_ROWS ]; - // Variable holding the sum over all independent white noise - // sources (used for optimization purposes). + /** + * Variable holding the sum over all independent white noise + * sources (used for optimization purposes) in the pink() + * function. + */ long runningSumPink; - // Internal time unit. + /** + * Internal time unit of the pink() function. + */ int indexPink; - // Determines the maximum possible value of `indexPink'. + /** + * Determines the maximum possible value of `indexPink'. + */ int indexMaskPink; - // Biggest possible value generated by the pink noise source. + /** + * Biggest possible value generated by the pink noise source + * pink(). + */ long maxValuePink; - // Normalization constant to transform the result of type - // long into float and in the range of -1.0 to +1.0. + /** + * Normalization constant to transform the result of the + * pink() function of type long into float and in the range of + * -1.0 to +1.0. + */ float normalizationPink; ////////////////////////////////////////////////////////////// }; diff --git a/src/core/src/randomizer.cpp b/src/core/src/randomizer.cpp index a23c7ef0de..86655768b8 100644 --- a/src/core/src/randomizer.cpp +++ b/src/core/src/randomizer.cpp @@ -29,11 +29,34 @@ namespace H2Core { Randomizer* Randomizer::__instance = 0; -// Constructor +/** + * @brief Constructor initializing the states of the individual + * colors. + * + * Since the \p uniform_white() function is used within the generation + * of all other colors the state of the uniform white noise generator + * is initialized first. This is done using a random seed drawn by the + * \p std::rand() function. The output of the \p std::rand() function + * will be of type integer and the first bits will be filled with + * zeros in the conversion into a 64 bit integer. But since this only + * affects the initialization step, it won't cause any problems within + * for the algorithms within used within the Randomizer. + * + * @return Object of class Randomizer. + */ Randomizer::Randomizer() : uniformStateInt64( 4101842887655102017LL ) { __instance = this; - // Generate a random seed + // + // Random seed used to initiate the Randomizer object. + // + // The output of the std::rand() function will be of type + // integer and the first bits will be filled with zeros in the + // conversion into a 64 bit integer. But since this only + // affects the initialization step, it won't cause any + // problems within for the algorithms within used within the + // Randomizer. + // unsigned long long int initialSeed = std::rand(); // // Initialize the white uniform noise source. @@ -49,7 +72,7 @@ Randomizer::Randomizer() : indexMaskPink = ( 1 << PINK_USED_ROWS ) - 1; // Biggest possible signed random value generated by the pink // noise generator. An extra 1 is added for the white noise - // source added to the pink noise. + // source added to the pink noise. maxValuePink = ( PINK_USED_ROWS + 1 ) * ( 1 << ( PINK_BITS - 1 ) ); // Normalization constant to convert the output into float. @@ -64,52 +87,79 @@ Randomizer::Randomizer() : runningSumPink = 0; } -// Create an instance within Hydrogen +/** + * Create an instance within Hydrogen + */ Randomizer* Randomizer::create_instance(){ if ( __instance == 0 ){ __instance = new Randomizer; } return __instance; } -// Retrieve a created instance +/** + * Retrieve the created instance + */ Randomizer* Randomizer::get_instance(){ assert( __instance ); return __instance; } /////////////////////// White uniform noise ////////////////////////// -// The uniform white noise generator is the basis for all colors -// produced by this struct. It will use the `Ranq1' code recommended -// by the book "Numerical Recipes" by Press et al. p. 351. It is a -// composed generator capable of producing random numbers (the -// std::rand() function produces slightly correlated output) and has -// a period of "only" 1.8 * 10^19. But for our use at hand it is more -// than sufficient. -// -// Composed generator with a multiplicative linear congruential -// generator as the outer method and a 64-bit Xorshift method as the -// inner one. +/** + * @brief Uniform white noise generator for 64 bit integers. + * + * A Composed generator with a multiplicative linear congruential + * generator as the outer method and a 64-bit Xorshift method as the + * inner one. + * + * The uniform white noise generator is the basis for all colors + * produced by this struct. It will use the *Ranq1* code recommended + * by the book "Numerical Recipes" by Press et al. p. 351. It is a + * composed generator capable of producing random numbers (the + * std::rand() function produces slightly correlated output) and has a + * period of \e only 1.8 * 10^19. But for our use at hand it is more + * than sufficient. + * + * @return A 64 bit integer uniformly and independently distributed + * random number. + */ unsigned long long int Randomizer::white_uniform_int64(){ uniformStateInt64 ^= uniformStateInt64 >> 21; uniformStateInt64 ^= uniformStateInt64 << 35; uniformStateInt64 ^= uniformStateInt64 >> 4; return uniformStateInt64 * 2685821657736338717LL; } -// Double precision version of the algorithm. +/** + * @brief Uniform white noise generator at double precision. + * + * @return A double precision uniformly and independently + * distributed random number. + */ double Randomizer::white_uniform(){ return 5.42101086242752217E-20 * white_uniform_int64(); } ////////////////////////////////////////////////////////////////////// ////////////////////////// Gaussian white noise ////////////////////// -// There are several algorithms for generating Gaussian white -// noise. But most of them just try to approximate the Gaussian nature -// of the signal. Instead the Box-Muller transformation will be used -// to transform uniformly distributed white noise into true Gaussian -// white noise. -// -// Box-Muller transformation. The resulting Gaussian random -// variable will be of mean 0 and of standard deviation -// `standardDeviation'. +/** + * @brief Gaussian white noise generator at double precision. + * + * This function is based on the Box-Muller transformation. The + * resulting Gaussian random variable will be of mean 0 and of + * standard deviation \p standardDeviation. + * + * While other algorithms do approximate the Gaussian nature of the + * generated noise this one will yield the most precise results + * because it is based on more mathematical exact transformation. + * + * @param standardDeviation A double precision number specifying the + * standard deviation, or square root of the variance, of the + * generated Gaussian white noise. + * + * @sa white_uniform + * + * @return A double precision independently and normally distributed + * random number. + */ double Randomizer::white_gaussian( double standardDeviation ){ double uniformRandomNumber1, uniformRandomNumber2, distance, factor; @@ -147,17 +197,26 @@ double Randomizer::white_gaussian( double standardDeviation ){ ////////////////////////////////////////////////////////////////////// /////////////////////////////// Pink noise /////////////////////////// -// The one over frequency behavior of a true pink spectrum will be -// approximated by summing a bunch of white noises, which are updated -// on different time scales. Those times are positioned equidistant on -// a logarithmic time scale. -// This algorithm will generate a fair 1/f spectrum with some -// inaccuracy at very low frequencies and is based on code snippet -// posted by Phil Burk on the music-dsp mailing -// list. http://www.firstpr.com.au/dsp/pink-noise/ -// The number of involved independent random white noises can be -// controlled using the `PINK_USED_ROWS' constant in the corresponding -// header file. +/** + * @brief Pink noise generator at double precision. + * + * The one over frequency behavior of a true pink spectrum will be + * approximated by summing a bunch of white noises, which are updated + * on different time scales. Those times are positioned equidistant on + * a logarithmic time scale. This algorithm will generate a fair 1/f + * spectrum with some inaccuracy at very low frequencies and is based + * on code snippet posted by Phil Burk on the music-dsp mailing + * list. http:www.firstpr.com.au/dsp/pink-noise/ The number of + * involved independent random white noises can be controlled using + * the \p PINK_USED_ROWS constant in the corresponding header file. + * + * @param scale A float number, which will be multiplied with the + * resulting pink random numbers. + * + * @sa white_uniform_int64 + * + * @return A pink random number at float precision + */ float Randomizer::pink( float scale ){ long uniformRandomNumber, sumUpdate; float output; @@ -187,7 +246,7 @@ float Randomizer::pink( float scale ){ // noise sources will not be calculated in every // run. Instead, the chosen one will be subtracted and // the updated value will be add back to - // `runningSumPink'. + // `runningSumPink'. runningSumPink -= rowsPink[ numberOfZeros ]; uniformRandomNumber = ( (long)white_uniform_int64() ) >> PINK_SHIFT;