tts_sample.c 8.0 KB
/*
* 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的
* 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的
* 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。
*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>


#include "include/qtts.h"
#include "include/msp_cmn.h"
#include "include/msp_errors.h"
#include "JZsdkLib.h"

#include "Megaphone_InputAndOutput.h"
#include "../Music/Megaphone_Music.h"
#include "tts_sample.h"


typedef int SR_DWORD;
typedef short int SR_WORD ;
const char*  TTS_ID    = NULL;
const char*  TTS_ID1    = NULL;
const char*  TTS_ID2    = NULL;
static int TTSLoopPlayMode;
extern int tts_add;			//追加声音

static int TTS_Play_flag = 0; //TTS播放标志位 用于暂停播放tts


/* 文本合成 */
int text_to_speech(const char* src_text, const char* des_path, const char* params)
{
	int          ret          = -1;
	const char*  sessionID    = NULL;
	const char*  sessionID1    = NULL;
	const char*  sessionID2    = NULL;
	unsigned int audio_len    = 0;
	int          synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;

	ret= -1;
	if (NULL == src_text || NULL == des_path)
	{
		printf("params is error!\n");
		return ret;
	}
	/* 开始合成 */	
	sessionID = QTTSSessionBegin(params, &ret);
	TTS_ID = sessionID;
	if (MSP_SUCCESS != ret)
	{
		printf("QTTSSessionBegin failed, error code: %d.\n", ret);
		return ret;
	}
	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 ret;
	}
	printf("正在合成 ...\n");
	while (TTS_Play_flag) 
	{
		/* 获取合成音频 */
		const char* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);
		if (MSP_SUCCESS != ret)
			break;
		//printf("获取成功,长度位%d\n",audio_len);
		if (NULL != data)
		{			
			Megaphone_RawPlay(16000, (unsigned char *)data,(int)audio_len);//播放合成的音频文件
			//printf("播放成功\n");
		}
		//else{printf("data==null\n");}
		
		if (MSP_TTS_FLAG_DATA_END == synth_status)
			break;
	}
	printf("\n");
	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);
	}
	return ret;
}

void login_tts(void){
	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;	
}





int play_tts(int name,int volume,int speed, char *argv, int ReplyFlag)
{
	int         ret                  = MSP_SUCCESS;
	char name_tts[16];
	char name_path[64];
	char session_begin_params[512];
	int tts_speed_add=50;
	int audio_volume = Music_get_music_volume();

	tts_speed_add=speed;
	/*
	* rdn:           合成音频数字发音方式
	* volume:        合成音频的音量
	* pitch:         合成音频的音调
	* speed:         合成音频对应的语速
	* voice_name:    合成发音人
	* sample_rate:   合成音频采样率
	* text_encoding: 合成文本编码格式
	*
	*/
	switch(name){
		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;
	}
	const char* filename             = "/root/record/1.wav"; //合成的语音文件名称      tts_res_path = fo|res/tts/xiaoyan.jet;fo|res/tts/common.jet,
	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);
	char tts_add1[512];
	char tts_add2[512];
	snprintf(tts_add1,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",tts_speed_add);
	snprintf(tts_add2,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",tts_speed_add);
	/* 文本合成 */
	printf("开始合成 ...\n");

	//修改音量
	Music_SetTTSvolume();

	//打开功放
	Megaphone_set_amplifier(1);

Start_TTS:
	ret = text_to_speech(argv, filename, session_begin_params);
	if (MSP_SUCCESS != ret)
	{
		printf("text_to_speech failed, error code: %d.\n", ret);
	}
	printf("合成完毕\n");
	if(tts_add==1){
		ret = text_to_speech(argv, filename, tts_add1);
		if (MSP_SUCCESS != ret)
		{
			printf("text_to_speech failed, error code: %d.\n", ret);
		}
		printf("追加女声合成完毕\n");
	}
	else if(tts_add==2){
		ret = text_to_speech(argv, filename, tts_add2);
		if (MSP_SUCCESS != ret)
		{
			printf("text_to_speech failed, error code: %d.\n", ret);
		}
		printf("追加男声合成完毕\n");
	}

	//如果循环播放标志被打开, 且处于TTS播放模式
	if(TTSLoopPlayMode==1 && TTS_Play_flag ==1)
	{
		delayMs(500);
		goto Start_TTS;
	}

	int time = strlen(argv) *60*speed/50;
	//如果处于TTS播放模式下 进行正常的TTS延时
	if (TTS_Play_flag == 1)
	{
		if (time < 4000)
		{
			printf("延时长度%d 字节长度%d \n",time, strlen(argv) );
			delayMs(time);
			
		}
		else
		{
			printf("延时长度4000" );
			delayMs(4000);
		}
	}

	//关闭播放
	Megaphone_audio_PlayStop();

	//恢复音量
	Megaphone_Set_Volume(audio_volume);

	//如果拥有回复标识
	if (ReplyFlag == 1)
	{	
		//回复播放状态结束
		Megaphone_Reply_PlayStatus_end();
	}

	
	return 0;
}

void Set_TTS_play_flag(int flag)
{
	TTS_Play_flag = flag;
}


int TTS_Get_TTS_play_flag()
{
	return TTS_Play_flag;
}

int TTS_Set_TTSLoopPlayMode(int mode)//设置播放模式,mode==1单曲播放。mode==2单曲循环
{
	TTSLoopPlayMode=mode;
}