#ifndef __CNOISE_C
#define __CNOISE_C
/*
* This code is distributed under GPLv3
*
* This code generates correlated or colored noise with a 1/f^alpha power
* spectrum distribution.
*
* It uses the algorithm by:
*
* Jeremy Kasdin
* Discrete Simulation of Colored Noise and Stochastic Processes and $ 1/f^\alpha $ Power Law Noise Generation
* Proceedings of the IEEE
* Volume 83, Number 5, 1995, pages 802-827.
*
* This code uses GSL fast Fourier transform gsl_fft_complex_forward(...)
* and the GCC rand() functions
*
* Code Author: Miroslav Stoyanov, Jan 2011
*
* Copyright (C) 2011 Miroslav Stoyanov
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Since the GNU General Public License is longer than this entire code,
* a copy of it can be obtained separately at
*
* updated June 2011: fixed a small bug causing "nan" to be returned sometimes
*
*/
#include "cnoise.h"
#define _CNOISE_PI 3.14159265358979323846 // pi
/******************************************************************************/
inline double cnoise_uniform01()
/******************************************************************************/
{
return ( ( (double) rand() + 1.0 ) / ( (double) RAND_MAX + 1.0 ) );
};
/******************************************************************************/
inline void cnoise_two_gaussian_truncated( double *a, double *b, double std, double range )
/******************************************************************************/
{
double gauss_u = cnoise_uniform01();
double gauss_v = cnoise_uniform01();
*a = std * sqrt( - 2 * log( gauss_u ) ) * cos( 2 * _CNOISE_PI * gauss_v );
*b = std * sqrt( - 2 * log( gauss_u ) ) * sin( 2 * _CNOISE_PI * gauss_v );
while ( (*a < -range) || (*a > range) ){
gauss_u = cnoise_uniform01(); gauss_v = cnoise_uniform01();
*a = std * sqrt( - 2 * log( gauss_u ) ) * cos( 2 * _CNOISE_PI * gauss_v );
};
while ( (*b < -range) || (*b > range) ){
gauss_u = cnoise_uniform01(); gauss_v = cnoise_uniform01();
*b = std * sqrt( - 2 * log( gauss_u ) ) * cos( 2 * _CNOISE_PI * gauss_v );
};
};
/******************************************************************************/
void cnoise_generate_colored_noise( double *x, int N, double alpha, double std )
/******************************************************************************/
{
gsl_fft_complex_wavetable * wavetable;
gsl_fft_complex_workspace * workspace;
int i;
double tmp;
double gauss_u, gauss_v;
double * fh = malloc( 4*N*sizeof(double) );
double * fw = malloc( 4*N*sizeof(double) );
fh[0] = 1.0; fh[1] = 0.0;
for( i=1; i