#include <stdio.h>
#include <string.h>
#include <pthread.h>

#include "./cnTTS.h"
#include "../Megaphone_TTS.h"
#include "../../Megaphone.h"

#include "AudioDeal/AudioDeal.h"

#include "JZsdkLib.h"

#include "version_choose.h"
#include "qtts.h"
#include "msp_cmn.h"
#include "msp_errors.h"
#include "msp_types.h"

#define TTS_SAVE 0

static T_JZsdkReturnCode TTS_Synthesis(const char* src_text, const char* params)
{
	int          ret          = -1;
	const char*  sessionID    = NULL;
	unsigned int audio_len    = 0;
	int          synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;

	unsigned char read_str[3*1276 + 3];

#if TTS_SAVE
	FILE *fp = fopen("/root/sdcard/tts_save.pcm", "wb+");
#endif

	if (src_text == NULL)
	{
		JZSDK_LOG_ERROR("params is error!\n");
		return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
	}

	/* 开始合成 */	
	sessionID = QTTSSessionBegin(params, &ret);

	JZSDK_LOG_INFO("%s",src_text);

	//将文本数据放入tts库
	ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);
	if (MSP_SUCCESS != ret)
	{
		printf("QTTSTextPut failed, error code: %d.\n",ret);
		QTTSSessionEnd(sessionID, "TextPutError");
		return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
	}

	printf("正在合成 ...\n");

	while (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON)
	{
		/* 获取合成音频 */
		const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);
		if (ret != MSP_SUCCESS)
		{
			break;
		}


		if (data != NULL)
		{
#if TTS_SAVE
			fwrite((unsigned char *)data, sizeof(unsigned char), audio_len, fp); // 写入数据  
#endif
			//没将数据放入PCM通道
			//printf("产生了%d 的数据\n",audio_len);
			AudioDeal_PcmDataInput(16000, (unsigned char *)data, audio_len);
		}

		if (synth_status == MSP_TTS_FLAG_DATA_END)
		{
			break;
		}	
	}
	
	if (MSP_SUCCESS != ret)
	{
		printf("QTTSAudioGet failed, error code: %d.\n",ret);
		QTTSSessionEnd(sessionID, "AudioGetError");
		return ret;
	}
	ret = QTTSSessionEnd(sessionID, "Normal");
	if (MSP_SUCCESS != ret)
	{
		printf("QTTSSessionEnd failed, error code: %d.\n",ret);
	}

#if TTS_SAVE
	fclose(fp);
#endif

}

/*************************
 * 
 *  获取音源
 * 
 * ********/
static T_JZsdkReturnCode TTS_GetSoundSource(int tone,unsigned char *name_tts, unsigned char *name_path)
{

	/*
	* rdn:           合成音频数字发音方式
	* volume:        合成音频的音量
	* pitch:         合成音频的音调
	* speed:         合成音频对应的语速
	* voice_name:    合成发音人
	* sample_rate:   合成音频采样率
	* text_encoding: 合成文本编码格式
	*
	*/
	switch(tone){
		case 0x01://中文女生
			snprintf(name_tts,16, "xiaoyan");
			snprintf(name_path,64, "fo|/root/tts/xiaoyan.jet");
			break;
		case 0x02://中文男生
			snprintf(name_tts,16, "xiaofeng");
			snprintf(name_path,64, "fo|/root/tts/xiaofeng.jet");
			break;
		case 0x11://英文女生
			snprintf(name_tts,16, "catherine");
			snprintf(name_path,64, "fo|/root/tts/catherine.jet");
			break;
		case 0x12://英文男生
			snprintf(name_tts,16, "john");
			snprintf(name_path,64, "fo|/root/tts/john.jet");
			break;
		case 0x31://东北
			snprintf(name_tts,16, "xiaoqian");
			snprintf(name_path,64, "fo|/root/tts/xiaoqian.jet");
			break;
		case 0x32://四川
			snprintf(name_tts,16, "xiaorong");
			snprintf(name_path,64, "fo|/root/tts/xiaorong.jet");
			break;
		case 0x33://河南
			snprintf(name_tts,16, "xiaokun");
			snprintf(name_path,64, "fo|/root/tts/xiaokun.jet");
			break;
		case 0x34://湖南
			snprintf(name_tts,16, "xiaoqiang");
			snprintf(name_path,64, "fo|/root/tts/xiaoqiang.jet");
			break;	
		case 0x35://陕西
			snprintf(name_tts,16, "xiaoying");
			snprintf(name_path,64, "fo|/root/tts/xiaoying.jet");
			break;	
		case 0x36://广东
			snprintf(name_tts,16, "xiaomei");
			snprintf(name_path,64, "fo|/root/tts/xiaomei.jet");
			break;				
		default://默认中文女生
			snprintf(name_tts,16, "xiaoyan");
			snprintf(name_path,64, "fo|/root/tts/xiaoyan.jet");
			break;
	}
}

static T_JZsdkReturnCode TTS_FILE_GenerateAndPlay(struct t_Megaphone_tts_param *Megaphone_tts_param)
{
	int tone = Megaphone_tts_param->tts_tone;
	int volume = Megaphone_tts_param->tts_volume;
	int speed = Megaphone_tts_param->tts_speed;
	char *argv = Megaphone_tts_param->ttsdata;
	int tts_add_mode = Megaphone_tts_param->tts_add;
	int ReplyFlag = Megaphone_tts_param->ReplyFlag;

	int  ret = MSP_SUCCESS;
	char name_tts[16];
	char name_path[64];
	char session_begin_params[512];
	char tts_add_params[512];

	//获取音源
	TTS_GetSoundSource(tone, name_tts, name_path);

	snprintf(session_begin_params,512,
			"engine_type = local,voice_name=%s, text_encoding = UTF8, tts_res_path = %s;fo|/root/tts/common.jet, sample_rate = 16000, speed = %d, volume = %d, pitch = 50, rdn = 2"
			,name_tts,name_path,speed,volume);

	printf("session_begin_params=%s\n",session_begin_params);
	printf("argv=%s\n",argv);

	//如果开启了语音追加
	if (tts_add_mode == 1)
	{
		snprintf(tts_add_params,512,
			"engine_type = local,voice_name=xiaoyan, text_encoding = UTF8, tts_res_path = fo|/root/tts/xiaoyan.jet;fo|/root/tts/common.jet, sample_rate = 16000, speed = %d, volume = 100, pitch = 50, rdn = 2"
			,speed);
	}
	else if (tts_add_mode == 2)
	{
		snprintf(tts_add_params,512,
			"engine_type = local,voice_name=xiaofeng, text_encoding = UTF8, tts_res_path = fo|/root/tts/xiaofeng.jet;fo|/root/tts/common.jet, sample_rate = 16000, speed = %d, volume = 100, pitch = 50, rdn = 2"
			,speed);
	}

	/* 文本合成 */
	printf("开始合成 ...\n");

	//合成文本音乐
	int loop;
	do
	{
		
		TTS_Synthesis(argv, session_begin_params);
		if (tts_add_mode != 0)
		{
			TTS_Synthesis(argv, tts_add_params);
		}

		Megaphone_param(JZ_FLAGCODE_GET, MEGAPHONE_LOOP, &loop);
		
	} while ( (loop == JZ_FLAGCODE_ON) && (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON));
	
	return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}



//TTS合成线程
static void *Play_cntts_pthread(void *arg)
{
	struct t_Megaphone_tts_param *Megaphone_tts_param = (struct t_Megaphone_tts_param *) arg;

	int ReplyFlag = Megaphone_tts_param->ReplyFlag;

	//设置标志位
	Megaphone_MegDataGenFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_ON);
	Megaphone_MegDataGenFinshFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_ON);

	//广播状态开始
	if (ReplyFlag == JZ_FLAGCODE_ON)
	{
		Megaphone_status_Broadcast(AUDIO_PLAY_STATUS_IFLAY_TTS);
	}
	
	int amplifier = JZ_FLAGCODE_ON;
    Megaphone_Amplifier_param(JZ_FLAGCODE_SET, &amplifier);

	//修改tts前的音量
	Megaphone_SetVolume(0, 1);

	//生成tts播放文件
	TTS_FILE_GenerateAndPlay(Megaphone_tts_param);

	//释放掉结构体和标志位
	JZsdk_Free(Megaphone_tts_param);

	//恢复音量
	int audio_volume = Megaphone_get_now_volume();
	Megaphone_SetVolume(audio_volume,0);

	amplifier = JZ_FLAGCODE_OFF;
    Megaphone_Amplifier_param(JZ_FLAGCODE_SET, &amplifier);

	Megaphone_MegDataGenFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_OFF);
	Megaphone_MegDataGenFinshFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_OFF);

	//广播关闭
	if (ReplyFlag == JZ_FLAGCODE_ON)
	{
		Megaphone_status_Broadcast(JZ_FLAGCODE_OFF);
	}

	JZSDK_LOG_INFO("TTS线程结束");
}


/*********
 * 
 *  tts注册
 * 
 * 
**********/
static void login_tts()
{
	int         ret                  = MSP_SUCCESS;
	int error_num=0;
	const char* login_params         = "appid = 03857dfd, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动
relogin:
	/* 用户登录 */
	ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名,第二个参数是密码,第三个参数是登录参数,用户名和密码可在http://www.xfyun.cn注册获取
	if (MSP_SUCCESS != ret&&error_num<10)
	{
		error_num+=1;
		printf("TTS Login failed, error code: %d num %d.\n", ret,error_num);
		goto relogin ;//登录失败,重新登录
	}
	else{
		printf("TTS login\n");
	}
	return;	
}

/*********
 * 
 *  tts初始化
 * 
**********/
T_JZsdkReturnCode Megaphone_cnTTS_Init()
{
	login_tts();
}



/*********
 * 
 *  讯飞TTS_播放函数
 * 
**********/
T_JZsdkReturnCode Megaphone_cnTTS_Play(unsigned char *str, unsigned int str_len, int ReplyFlag)
{
	//1、制造一个数据产生函数
	pthread_t TTS_flie_task;
	pthread_attr_t task_attribute; //线程属性
	pthread_attr_init(&task_attribute);  //初始化线程属性
	pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED);      //设置线程属性

	//tts参数结构体
	struct t_Megaphone_tts_param *Megaphone_tts_param = NULL;
	if(JZsdk_Malloc( (void **)&Megaphone_tts_param, sizeof(struct t_Megaphone_tts_param)) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)//如果申请内存失败,malloc会返回一个NULl
	{
		printf("malloc use failure");
		return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;//申请内存失败,错误退出
	}

	//清空参数
	memset (Megaphone_tts_param,0,sizeof(struct t_Megaphone_tts_param));

	//写入参数
	Megaphone_tts_param->tts_speed = TTS_Get_speed();
	Megaphone_tts_param->tts_tone =  TTS_Get_tone();
	Megaphone_tts_param->tts_volume = TTS_Get_NormalVolume();
	Megaphone_tts_param->tts_add = TTS_Get_TTS_AppendTone();
	Megaphone_tts_param->ReplyFlag = ReplyFlag;
	memset(Megaphone_tts_param->ttsdata,0,sizeof(Megaphone_tts_param->ttsdata));
	memcpy(Megaphone_tts_param->ttsdata, str, str_len);

	int tts_ret = pthread_create(&TTS_flie_task,&task_attribute,Play_cntts_pthread,(void *)Megaphone_tts_param);		//TTS线程
	if(tts_ret != 0)
	{
		printf("创建TTS线程失败\n");
		return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
	}

	return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}