/*
 * GHDSS.h
 *
 */

#ifndef GHDSS_H_
#define GHDSS_H_

//////////#include "header.h"
#include "android_hark.h"

#ifdef __cplusplus
extern "C" {
#endif

//#define GHDSS_CUDA_ENABLE

#ifdef GHDSS_CUDA_ENABLE

typedef struct
{
	HA_Complex	A[ARY_NUM_FFT][ARY_NUM_MIC][ARY_NUM_SRC];		// 演算用配列
	HA_Complex	W[ARY_NUM_FFT][ARY_NUM_SRC][ARY_NUM_MIC];		// 演算用配列（分離行列）
	HA_Complex	X[ARY_NUM_FFT][ARY_NUM_MIC];					// 演算用配列（マイクの入力）
	HA_Complex	Y[ARY_NUM_FFT][ARY_NUM_SRC];					// 演算用配列

	HA_Complex	J_SS[ARY_NUM_FFT][ARY_NUM_SRC][ARY_NUM_MIC];	// μSS
	HA_Complex	J_LC[ARY_NUM_FFT][ARY_NUM_SRC][ARY_NUM_MIC];	// μLC

	HA_Complex 	PY[ARY_NUM_FFT][ARY_NUM_SRC];					// PY
	HA_Complex 	QY[ARY_NUM_FFT][ARY_NUM_SRC];					// QY
} ST_KERNEL_WORK;

extern int GHDSS_cudaMallocHost(void **ptr, size_t size);
extern int GHDSS_cudaFreeHost(void *ptr);
extern int GHDSS_init(const int thread_no);
extern int GHDSS_release(const int thread_no);

#endif

//extern int	InitTFMatrix(void);
extern int	InitTFMatrix(char *tf_file_name);

extern void ClearGHDSS(void);
extern void ClearHRLE(void);
extern void ClearDelta(void);
extern void ClearEstimateLeak(void);
extern void ClearMelFilterBank(void);
extern void ClearPreEmphasis(void);

extern void makeConjWindow(void);

extern void HAInitDelta(void);
extern void HAInitEstimateLeak(void);
extern void HAInitMelFilterBank(void);
extern void HAInitPreEmphasis(void);

extern int HASetParamDelta(int *);
extern int HASetParamEstimateLeak(Param_EstimateLeak_t *);
extern int HASetParamMelFilterBank(Param_MelFilterBank_t *);
extern int HASetParamPreEmphasis(Param_PreEmphasis_t *);

/* 2013.08.05 K.Takagi */
extern int HASetParamWhiteNoiseAdder(Param_WhiteNoiseAdder_t *param);
extern int HAGetParamWhiteNoiseAdder(Param_WhiteNoiseAdder_t *param);
extern int HASetParamHRLE(Param_HRLE_t *param);
extern int HAGetParamHRLE(Param_HRLE_t *param);

extern int Synthesize
	(
	int num_src,
	int count,
	HA_Complex	inputSpec[ARY_NUM_SRC][ARY_NUM_FFT],
	HA_Float	outputWave[ARY_NUM_SRC][ARY_NUM_WAVE]
	);

extern	int	GHDSS_core
		(
		const int,
		int,
		int,
		HA_Complex [ARY_NUM_MIC][ARY_NUM_FFT], // inputSpec
		MICARY_Location *,                     // inputLocation
		HA_Complex [ARY_NUM_SRC][ARY_NUM_FFT]  // outputSpec
		);

extern	int	PowerCalcForMap
		(
		int,
		HA_Complex [ARY_NUM_MIC][ARY_NUM_FFT],	// inputSpec
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT]		// outputSpec
		);

extern	int	HRLE
		(
		int,
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// inputSpec
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT]		// outputPowerSpec
		);

extern	int	EstimateLeak
		(
		int,
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// inputSpec
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT]		// outputPowerSpec
		);

extern	int	CalcSpecAddPower
		(
		int,
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// inputSpec from HRLE
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// inputSpec from EstimateLeak
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT]		// outputPowerSpec
		);

extern	int	CalcSpecSubGain
		(
		int,
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// inputSpec
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// inputSpec
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// output
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT],	// outputSpec
		HA_Float [ARY_NUM_SRC][ARY_NUM_FFT]		// output
		);

extern int	SpectralGainFilter
		(
		int,
		HA_Complex	[ARY_NUM_SRC][ARY_NUM_FFT], // 分離音声
		HA_Float	[ARY_NUM_SRC][ARY_NUM_FFT], // 音声存在確率
		HA_Float	[ARY_NUM_SRC][ARY_NUM_FFT], // Gain
		HA_Complex	[ARY_NUM_SRC][ARY_NUM_FFT]  // 出力音声
		);

extern 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]
	);

extern int	PreEmphasis
	(
	int	num_src,
	int	count,
//	HA_Float	inputWave[ARY_NUM_SRC][ARY_NUM_WAVE],
//	HA_Float	outputWave[ARY_NUM_SRC][ARY_NUM_WAVE]
	HA_Complex	inputSpec[ARY_NUM_SRC][ARY_NUM_FFT],
	HA_Complex	outputSpec[ARY_NUM_SRC][ARY_NUM_FFT]
	);

extern int	MelFilterBank
	(
	int	num_src,
	int	count,
	HA_Complex	inputSpec[ARY_NUM_SRC][ARY_NUM_FFT],	// 入力はComplexのみ
	HA_Float	outputFbank[ARY_NUM_SRC][ARY_NUM_FBANK*2]
	);

extern int	MSLSExtraction
	(
	int	num_src,
	HA_Complex	spec[ARY_NUM_SRC][ARY_NUM_FFT],			// 入力スペクトル
	HA_Float	input_fbank[ARY_NUM_SRC][ARY_NUM_FBANK*2],
	HA_Float	output_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER]
	);

extern int	Delta
	(
	int	num_src,
	int	count,
	HA_Float	input_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER],
	HA_Float	output_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER]
	);

extern int	PowerFeatureRemover
	(
	int	num_src,
	HA_Float	input_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER],
	HA_Float	output_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER]
	);

extern int	FeatureRemover
	(
	int	num_src,
	HA_Float	input_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER],
	HA_Float	output_fbank[ARY_NUM_SRC][ARY_NUM_FBANK_DELTA_POWER],
	int remove_vec[ARY_NUM_FBANK_DELTA_POWER]
	);

#ifdef __cplusplus
}
#endif


#endif /* GHDSS_H_ */
