
/************************************************************
**	WhiteNoiseAdder.c
**
**  Private :
**
**  History :
**     2013.05.14 M.Takigahira Build有無指定に対応
**     2013.05.08 M.Takigahira 処理精査、パラメータ設定に対応、
**                             ノイズ印加無し時の処理を軽減
**     2013.01.10 kama@SIF     新規作成(V1.0)
**
**  Description
**  -----------
**  入力信号に白色ノイズを付加する
**  STATUS	WhiteNoiseAdder
**  入力1　：スペクトル
**  出力1　：ノイズを付加したスペクトル
**
**  	処理の内容
**
**  	1) 各周波数ビンについて以下の計算を行う
**  		√LENGTH /2 ・ WN_LEVEL ・ e^(2πjR)
**
**  	以上。
**
*/

///////////////////////////////////////////////////////////////
//  Include Files
#include "build_modules.h"
//////////#include "header.h"
#include "HA_log.h"
#include "android_hark.h"

///////////////////////////////////////////////////////////////
//  Define Macros
#define LOCAL_DEFAULT_WN_FACTOR 300.0f

#if !defined BUILD_MODULE_WHITE_NOISE_ADDER
///////////////////////////////////////////////////////////////
//  Dummy Functions for build empty methods.
int HASetParamWhiteNoiseAdder(Param_WhiteNoiseAdder_t *param){ return 0; }
int	WhiteNoiseAdder(int num_src, HA_Complex spec_in[ARY_NUM_SRC][ARY_NUM_FFT], HA_Complex spec_out[ARY_NUM_SRC][ARY_NUM_FFT]){ return 0; }
#else // #if defined BUILD_MODULE_WHITE_NOISE_ADDER
///////////////////////////////////////////////////////////////
//  Parameter
const float rand_coef = M_PI * 2.0f / (float)RAND_MAX;
static float wn_factor = 3394.1125496954281171240529381033f; // ((sqrt(ARY_NUM_WAVE/2.0f)) * 300.0f)  =  ((sqrt(512)/2.0f) * 300.0f)

static Param_WhiteNoiseAdder_t whitenoise_param = {
	ARY_NUM_WAVE,
	ARY_NUM_FFT,
	LOCAL_DEFAULT_WN_FACTOR
};

///////////////////////////////////////////////////////////////
//  Local Buffer

///////////////////////////////////////////////////////////////
//  Clear

///////////////////////////////////////////////////////////////
//  Initialize

///////////////////////////////////////////////////////////////
//  SetParam
int HASetParamWhiteNoiseAdder(Param_WhiteNoiseAdder_t *param)
{
	float factor_tmp = 0.0f;
	if(param->length < 1){
		return -1;
	}
	if(param->fft_length < 1){
		return -1;
	}
	if(param->wn_level < 0.0f){
		return -1;
	}
	whitenoise_param = *param;
	wn_factor = (sqrtf(param->length) * 0.5f) * param->wn_level;
	return 0;
}

int HAGetParamWhiteNoiseAdder(Param_WhiteNoiseAdder_t *param)
{
	*param = whitenoise_param;
	return 0;
}

///////////////////////////////////////////////////////////////
//  MAIN
int	WhiteNoiseAdder
	(
	int	num_src,
	HA_Complex	spec_in[ARY_NUM_SRC][ARY_NUM_FFT],
	HA_Complex	spec_out[ARY_NUM_SRC][ARY_NUM_FFT]
	)
{
	int s, f;
	float theta;
	const num_fft = whitenoise_param.fft_length;
	// wn_factor == (sqrt(length)/2.0) * wn_level
	if(wn_factor > 0.0f){
		//const float coef = M_PI * 2.0f / (float)RAND_MAX;
		for(s=0; s!=num_src; ++s){
			for(f=0; f<num_fft; f++){
				theta = (float)rand() * rand_coef;
				//theta = M_PI;	// ノイズを印加しない for debug
				spec_out[s][f].re = spec_in[s][f].re + wn_factor * cos(theta);
				spec_out[s][f].im = spec_in[s][f].im + wn_factor * sin(theta);
			}
		}
	}
	else{ // ノイズを印加しない
		for(s=0; s!=num_src; ++s){
			for(f=0; f<num_fft; f++){
				spec_out[s][f].re = spec_in[s][f].re;
				spec_out[s][f].im = spec_in[s][f].im;
			}
		}
	}
	return(OK);
}
#endif // BUILD_MODULE_WHITE_NOISE_ADDER

// EOF
