
/************************************************************
**	ZeroCross_s.c
**
**  Private :
**
**  History :
**     2013.05.14 M.Takigahira Build有無指定に対応
**     2013.04.24 S.Miyazaki   新規作成(V1.0)
**
**  Description
**  -----------
**  ZeroCross検出
**  入力1　：
**  出力1　：
**
*/

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

#include "HABuffer.h"

///////////////////////////////////////////////////////////////
//  Define Macros

#if !defined BUILD_MODULE_ZERO_CROSS_S
///////////////////////////////////////////////////////////////
//  Dummy Functions for build empty methods.
void ClearZeroCross_s(void){ }
int	ZeroCross_s(int	num_src, HA_Float inputWave[ARY_NUM_SRC][ARY_NUM_WAVE], SOURCE_DATA_ARY_t *sources){ return 0; }
#else // #if defined BUILD_MODULE_ZERO_CROSS_S
///////////////////////////////////////////////////////////////
//  Parameter
int length;
float ampthresh;
int cross_thresh;
int speech_con_frames;
int pre_result[500];
short is_debug;
int frame_count;

int src_id;

int preroll_length;

FILE *fout; //miyazaki for debug

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

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

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

///////////////////////////////////////////////////////////////
//  SetParam

///////////////////////////////////////////////////////////////
//  MAIN
void ClearZeroCross_s(void)
{
	length            = 512;

	//ampthresh         = 0.6;
	//ampthresh         = 0.2;
	ampthresh         = 0.05;
	//ampthresh         = 0.002;
	//ampthresh         = 0.0;

	cross_thresh      = 10;
	//speech_con_frames = 3;
	speech_con_frames = 70;
	is_debug          = 1;
	//is_debug          = 0;
	frame_count       = 0;

	src_id = 0;

	preroll_length    = 50;

	memset(pre_result, 0, sizeof(int) * 500);

}

int initZeroCorss_debug()
{

#ifdef ENABLE_ANDROID_PATH
	if ((fout = fopen("/mnt/sdcard/hark2/zero_cross.txt", "wt")) == NULL){
				LOGE("%s open error.", "/mnt/sdcard/hark2/zero_cross.txt");
	}
#else
	if ((fout = fopen("/media/SD/hark2/zero_cross.txt", "wt")) == NULL){
				LOGE("%s open error.", "/media/SD/hark2/zero_cross.txt");
	}
#endif

	return(OK);
}

void finalizeZeroCorss_debug()
{
	fclose(fout);
}

int	ZeroCross_s
	(
	int	num_src,
	HA_Float	inputWave[ARY_NUM_SRC][ARY_NUM_WAVE], // 入力音声
	SOURCE_DATA_ARY_t *sources                        // count番号入力：発話区間出力
	)
{
	int cross_vec[1024];
	int s_idx;
	int i;

	memset(cross_vec, 0, sizeof(int) * 1024);

	frame_count = sources->count;

	//LOGD("    ZeroCross_s Start [%d]", frame_count);

	for(s_idx=0; s_idx<num_src; s_idx++){

		// 振幅閾値処理
		if(is_debug){
			int sum=0;
			for (i=0;i<length;i++){
				sum=sum+fabs(inputWave[s_idx][i]);
			}
			LOGD("average amplitude : %f \n", sum/(float)length);
		}

		/*
		for (i=0;i<length;i++){
			if(fabs(inputWave[s_idx][i]/32768)<ampthresh){
				inputWave[s_idx][i]=0;
			}
		}

		// 交差点探索
		int sig; // 符号 0:- 1:+
		if(inputWave[s_idx][0] < 0){
			sig = 0;
		}
		else{
			sig = 1;
		}

		int temp;
		for(i=1;i<length-1;i++){
			if(inputWave[s_idx][i] < 0){
				temp = 0;
			}
			else{
				temp = 1;
			}

			if(temp != sig){
				cross_vec[i] = 1;
				sig=temp;
			}
		}

		// 区間検出
		int sum=0;
		for(i=0;i<length-1;i++){
			sum = sum + cross_vec[i];
		}
		*/

		// 初期値設定
		int sum=0;
		int temp;
		int sig; // 符号 0:- 1:+
		if(inputWave[s_idx][0] < 0){
			sig = 0;
		}else{
			sig = 1;
		}

		for (i=0;i < length-1;i++){
			if(fabs(inputWave[s_idx][i]/32768) >= ampthresh){
				// 交差点探索
				if(inputWave[s_idx][i] < 0){
					temp = 0;
				}else{
					temp = 1;
				}

				if(temp != sig){
					cross_vec[i] = 1;
					sig=temp;
				}

				sum = sum + cross_vec[i];
			}
		}

		LOGD("    sum = %d", sum);
		fprintf(fout, "%d %d \n", frame_count, sum);

		// 複数前の出力を確認
		int flag = 0;
		for(i=0;i<speech_con_frames;i++){
			if(pre_result[i]==1){
				flag=1;
				break;
			}
		}

		//RCPtr<Source> src(new Source);

		if(flag==1){
			if(sum > cross_thresh){
				LOGD("    src_id=%d.", src_id);

				sources->data[s_idx].id = src_id;
				sources->data[s_idx].power = 1.0;
				sources->data[s_idx].x[0] = 1.0;
				sources->data[s_idx].x[1] = 0.0;
				sources->data[s_idx].x[2] = 0.0;
				pre_result[frame_count % speech_con_frames]=1;
			}
			else{
				LOGD("    src_id=%d.(con_frames)", src_id);

				sources->data[s_idx].id = src_id;
				sources->data[s_idx].power = 1.0;
				sources->data[s_idx].x[0] = 1.0;
				sources->data[s_idx].x[1] = 0.0;
				sources->data[s_idx].x[2] = 0.0;
				pre_result[frame_count % speech_con_frames]=0;
			}
		}
		else{
			if(sum > cross_thresh){
				LOGD("    src_id++.");

				src_id++;
				sources->data[s_idx].id = src_id;
				sources->data[s_idx].power = 1.0;
				sources->data[s_idx].x[0] = 1.0;
				sources->data[s_idx].x[1] = 0.0;
				sources->data[s_idx].x[2] = 0.0;
				pre_result[frame_count % speech_con_frames]=1;
			}
			else{
				pre_result[frame_count % speech_con_frames]=0;
			}
		}
	}

	//IntervalExtender section
    int sub_count;
    int add_flag;
    int index;
    int index2;
    SOURCE_DATA_ARY_t *src_ptr;
    SOURCE_DATA_ARY_t new_sources;

    if(frame_count < 0){
        return -1;
    }

    // 現在位置に追加
    HABufferSetSourceData(sources->count, sources);

    sub_count = frame_count - preroll_length;
    if(sub_count < 0){
        return -1;
    }

    // 遡った位置に追加
    if(sources->source_num > 0){
        src_ptr = HABufferGetZCSourceData(sub_count);

        for(index=0; index<src_ptr->source_num; index++){
            new_sources.data[index] = src_ptr->data[index];
        }
        new_sources.source_num = src_ptr->source_num;

        for(index=0; index<sources->source_num; index++){
            add_flag = 1;
            for(index2=0; index2<src_ptr->source_num; index2++){
                if(sources->data[index].id == src_ptr->data[index2].id){
                    add_flag = 0;
                }
            }

            if(add_flag){
                new_sources.data[new_sources.source_num] = sources->data[index];
                new_sources.source_num++;
            }
        }
        HABufferSetZCSourceData(sub_count, &new_sources);
    }

    // 改めて遡った位置のデータを返す
    src_ptr = HABufferGetZCSourceData(sub_count);
    for(index=0; index<src_ptr->source_num; index++){
        sources->data[index] = src_ptr->data[index];
    }
    sources->count = src_ptr->count;
    sources->source_num = src_ptr->source_num;

	return(OK);
}
#endif // BUILD_MODULE_ZERO_CROSS_S

// EOF
