int text_to_speech(byte *buf, int len) { const char* sess_id = NULL; char *obuf = NULL; unsigned int audio_len = 0; unsigned int olen = 0; int synth_status = 1; int ret = 0; byte erlret = 0; debug("Texting to speech %d bytes, %s", len, buf); ret = MSPLogin(NULL, NULL, login_configs); if ( ret != MSP_SUCCESS ) { debug("MSPLogin failed: %d", ret); return ret; } sess_id = QTTSSessionBegin(tts_params, &ret); if ( ret != MSP_SUCCESS ) { debug("QTTSSessionBegin failed: %d", ret); return ret; } ret = QTTSTextPut(sess_id, buf, len, NULL ); if ( ret != MSP_SUCCESS ) { debug("QTTSTextPut failed: %d", ret); QTTSSessionEnd(sess_id, "TextPutError"); return ret; } while (1) { const void *data = QTTSAudioGet(sess_id, &audio_len, &synth_status, &ret); if (NULL != data) { obuf = realloc(obuf, olen+audio_len); memcpy(obuf+olen, data, audio_len); olen += audio_len; } usleep(15000); if (synth_status == 2 || ret != 0) break; } debug("got %d bytes speech", olen); write_head(sizeof(erlret)+olen); write_exact(&erlret, sizeof(erlret)); write_exact(obuf, olen); free(obuf); QTTSSessionEnd(sess_id, NULL); MSPLogout(); return 0; }
int Text2Audio::getAudio(const char* src_text ,const char* des_path) { struct wave_pcm_hdr pcmwavhdr = default_pcmwavhdr; const char* sess_id = NULL; int ret = 0; unsigned int text_len = 0; char* audio_data; unsigned int audio_len = 0; int synth_status = 1; FILE* fp = NULL; printf("begin to synth...\n"); if (NULL == src_text || NULL == des_path) { printf("params is null!\n"); return -1; } text_len = (unsigned int)strlen(src_text); fp = fopen(des_path,"wb"); if (NULL == fp) { printf("open file %s error\n",des_path); return -1; } sess_id = QTTSSessionBegin(params, &ret); if ( ret != MSP_SUCCESS ) { printf("QTTSSessionBegin: qtts begin session failed Error code %d.\n",ret); return ret; } ret = QTTSTextPut(sess_id, src_text, text_len, NULL ); if ( ret != MSP_SUCCESS ) { printf("QTTSTextPut: qtts put text failed Error code %d.\n",ret); QTTSSessionEnd(sess_id, "TextPutError"); return ret; } fwrite(&pcmwavhdr, sizeof(pcmwavhdr) ,1, fp); while (1) { const void *data = QTTSAudioGet(sess_id, &audio_len, &synth_status, &ret); if (NULL != data) { fwrite(data, audio_len, 1, fp); pcmwavhdr.data_size += audio_len;//修正pcm数据的大小 } if (synth_status == 2 || ret != 0) break; } //修正pcm文件头数据的大小 pcmwavhdr.size_8 += pcmwavhdr.data_size + 36; //将修正过的数据写回文件头部 fseek(fp, 4, 0); fwrite(&pcmwavhdr.size_8,sizeof(pcmwavhdr.size_8), 1, fp); fseek(fp, 40, 0); fwrite(&pcmwavhdr.data_size,sizeof(pcmwavhdr.data_size), 1, fp); fclose(fp); ret = QTTSSessionEnd(sess_id, NULL); if ( ret != MSP_SUCCESS ) { printf("QTTSSessionEnd: qtts end failed Error code %d.\n",ret); } return ret; }
/* 文本合成 */ int text_to_speech(const char* src_text, const char* des_path, const char* params) { int ret = -1; FILE* fp = NULL; const char* sessionID = NULL; unsigned int audio_len = 0; wave_pcm_hdr wav_hdr = default_wav_hdr; int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; if (NULL == src_text || NULL == des_path) { printf("params is error!\n"); return ret; } fp = fopen(des_path, "wb"); if (NULL == fp) { printf("open %s error.\n", des_path); return ret; } /* 开始合成 */ sessionID = QTTSSessionBegin(params, &ret); if (MSP_SUCCESS != ret) { printf("QTTSSessionBegin failed, error code: %d.\n", ret); fclose(fp); 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"); fclose(fp); return ret; } printf("正在合成 ...\n"); fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000 while (1) { /* 获取合成音频 */ const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret); if (MSP_SUCCESS != ret) break; if (NULL != data) { fwrite(data, audio_len, 1, fp); wav_hdr.data_size += audio_len; //计算data_size大小 } if (MSP_TTS_FLAG_DATA_END == synth_status) break; printf(">"); usleep(150*1000); //防止频繁占用CPU }//合成状态synth_status取值请参阅《讯飞语音云API文档》 printf("\n"); if (MSP_SUCCESS != ret) { printf("QTTSAudioGet failed, error code: %d.\n",ret); QTTSSessionEnd(sessionID, "AudioGetError"); fclose(fp); return ret; } /* 修正wav文件头数据的大小 */ wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8); /* 将修正过的数据写回文件头部,音频文件为wav格式 */ fseek(fp, 4, 0); fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值 fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置 fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值 fclose(fp); fp = NULL; /* 合成完毕 */ ret = QTTSSessionEnd(sessionID, "Normal"); if (MSP_SUCCESS != ret) { printf("QTTSSessionEnd failed, error code: %d.\n",ret); } return ret; }
//语音合成 int Msc_QTTS_Tools::text_to_speech(const char* src_text ,const char* des_path ,const char* params) { struct wave_pcm_hdr pcmwavhdr = default_pcmwavhdr; const char* sess_id = NULL; int ret = 0; unsigned int text_len = 0; char* audio_data; unsigned int audio_len = 0; int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; FILE* fp = NULL; int pos = 0; //用于标记上一次已经合成到的位置 int loop_count = 0; //用于标记,取了几次结果 int upload_flow = 0,download_flow = 0;//上传流量和下载流量 char param_value[32] = "";//参数值的字符串形式 unsigned int value_len = 32; //字符串长度或buffer长度 printf("begin to synth...\n"); if (NULL == src_text || NULL == des_path) { printf("params is null!\n"); return -1; } text_len = (unsigned int)strlen(src_text); fp = fopen(des_path,"wb"); if (NULL == fp) { printf("open file %s error\n",des_path); return -1; } sess_id = QTTSSessionBegin(params, &ret); if ( ret != MSP_SUCCESS ) { printf("QTTSSessionBegin: qtts begin session failed Error code %d.\n",ret); return ret; } ret = QTTSTextPut(sess_id, src_text, text_len, NULL ); if ( ret != MSP_SUCCESS ) { printf("QTTSTextPut: qtts put text failed Error code %d.\n",ret); QTTSSessionEnd(sess_id, "TextPutError"); return ret; } fwrite(&pcmwavhdr, 1, sizeof(pcmwavhdr), fp); while ( true ) { audio_data = (char*)QTTSAudioGet( sess_id ,&audio_len , &synth_status , &ret ); fwrite(audio_data, 1, audio_len, fp); pcmwavhdr.data_size += audio_len;//修正pcm数据的大小 if ( MSP_TTS_FLAG_DATA_END == synth_status ) { printf("QTTSAudioGet: get end of data.\n"); break; } } //修正pcm文件头数据的大小 pcmwavhdr.size_8 += pcmwavhdr.data_size + 36; //将修正过的数据写回文件头部 fseek(fp, 4, 0); fwrite(&pcmwavhdr.size_8,sizeof(pcmwavhdr.size_8), 1, fp); fseek(fp, 40, 0); fwrite(&pcmwavhdr.data_size,sizeof(pcmwavhdr.data_size), 1, fp); fclose(fp); ret = QTTSSessionEnd(sess_id, "Normal"); if ( ret != MSP_SUCCESS ) { printf("QTTSSessionEnd: qtts end failed Error code %d.\n",ret); } return ret; }
int TTSHelper::CreateWaveAudioFile(const char *szText,const char *audioFileName) { const char* m_configs = ttsconf.m_configs; const char* szParam = ttsconf.szParam; printf("begin to synth...\n"); int ret = QTTSInit(m_configs); if ( ret != MSP_SUCCESS ) { LastErrorInfo="QTTSInit: qtts init failed, ret = "+ret; return ret; } //每次合成时,需要将这两个数据清零 pcmwavhdr.size_8=0; pcmwavhdr.data_size=0; const char* sess_id = QTTSSessionBegin(szParam, &ret); if ( ret != MSP_SUCCESS ) { //printf("QTTSSessionBegin: qtts begin session failed Error code %d.\n",ret); LastErrorInfo="QTTSSessionBegin: qtts begin session failed Error code: "+ret; QTTSFini(); return ret; } int len = strlen(szText); ret = QTTSTextPut(sess_id, szText, len, NULL ); if ( ret != MSP_SUCCESS ) { //printf("QTTSTextPut: qtts put text failed Error code %d.\n",ret); LastErrorInfo="QTTSTextPut: qtts put text failed Error code: "+ret; QTTSSessionEnd(sess_id, ""); QTTSFini(); return ret; } char* audio_data; unsigned int audio_len = 0; int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; const char* tmpname = audioFileName; FILE* fp = fopen(tmpname, "wb"); if ( fp == NULL ) { LastErrorInfo="Failed to open file: "+string(tmpname); QTTSSessionEnd(sess_id, ""); QTTSFini(); return ret; } //写入音频头部数据 fwrite(&pcmwavhdr, 1, sizeof(pcmwavhdr), fp); int pos = 0; //用于标记上一次已经合成到的位置 int loop_count = 0; //用于标记,取了几次结果 int upload_flow = 0,download_flow = 0;//上传流量和下载流量 char param_value[32] = "";//参数值的字符串形式 size_t value_len = 32; //字符串长度或buffer长度 while ( true ) { audio_data = (char*)QTTSAudioGet( sess_id ,&audio_len , &synth_status , &ret ); if ( ret != MSP_SUCCESS ) { LastErrorInfo="QTTSAudioGet: qtts get audio failed Error code: "+ret; char key = _getch(); break; } fwrite(audio_data, 1, audio_len, fp); pcmwavhdr.data_size += audio_len;//修正pcm数据的大小 if ( MSP_TTS_FLAG_DATA_END == synth_status ) { printf("QTTSAudioGet: get end of data.\n"); break; } } //修正pcm文件头数据的大小 pcmwavhdr.size_8 += pcmwavhdr.data_size + 36; //将修正过的数据写回文件头部 fseek(fp, 4, 0); fwrite(&(pcmwavhdr.size_8),sizeof(pcmwavhdr.size_8), 1, fp); fseek(fp, 40, 0); fwrite(&(pcmwavhdr.data_size),sizeof(pcmwavhdr.data_size), 1, fp); fclose(fp); ret = QTTSSessionEnd(sess_id, ""); if ( ret != MSP_SUCCESS ) { //printf("QTTSSessionEnd: qtts end failed Error code %d.\n",ret); LastErrorInfo="QTTSSessionEnd: qtts end failed Error code: "+ret; char key = _getch(); QTTSFini(); return ret; } ret = QTTSFini(); if ( ret != MSP_SUCCESS ) { //printf("CMSPAudioCtrl::PlayText: qtts fini failed Error code %d.\n",ret); LastErrorInfo="CMSPAudioCtrl::PlayText: qtts fini failed Error code: "+ret; char key = _getch(); return ret; } filebuf *pbuf; ifstream filestr; long size; // 要读入整个文件,必须采用二进制打开 filestr.open (audioFileName, ios::binary); // 获取filestr对应buffer对象的指针 pbuf=filestr.rdbuf(); // 调用buffer对象方法获取文件大小 size=pbuf->pubseekoff (0,ios::end,ios::in); pbuf->pubseekpos (0,ios::in); // 分配内存空间 AudioBuffer=new char[size]; AudioSize=size; // 获取文件内容 pbuf->sgetn (AudioBuffer,size); filestr.close(); return 0; }
int text_to_speech(const char* src_text ,const char* des_path ,const char* params) { struct wave_pcm_hdr pcmwavhdr = default_pcmwavhdr; const char* sess_id = NULL; int ret = 0; unsigned int text_len = 0; char* audio_data; unsigned int audio_len = 0; int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; FILE* fp = NULL; int pos = 0; //用于标记上一次已经合成到的位置 int loop_count = 0; //用于标记,取了几次结果 int upload_flow = 0,download_flow = 0;//上传流量和下载流量 char param_value[32] = "";//参数值的字符串形式 unsigned int value_len = 32; //字符串长度或buffer长度 printf("begin to synth...\n"); if (NULL == src_text || NULL == des_path) { printf("params is null!\n"); return -1; } text_len = (unsigned int)strlen(src_text); fp = fopen(des_path,"wb"); if (NULL == fp) { printf("open file %s error\n",des_path); return -1; } sess_id = QTTSSessionBegin(params, &ret); if ( ret != MSP_SUCCESS ) { printf("QTTSSessionBegin: qtts begin session failed Error code %d.\n",ret); return ret; } ret = QTTSTextPut(sess_id, src_text, text_len, NULL ); if ( ret != MSP_SUCCESS ) { printf("QTTSTextPut: qtts put text failed Error code %d.\n",ret); QTTSSessionEnd(sess_id, "TextPutError"); return ret; } fwrite(&pcmwavhdr, 1, sizeof(pcmwavhdr), fp); while ( true ) { audio_data = (char*)QTTSAudioGet( sess_id ,&audio_len , &synth_status , &ret ); /****************获取合成位置*****************///如果不需要该功能,本段可以删除 const char* audio_info = QTTSAudioInfo(sess_id); //获取已经得到的音频的位置 int ced = atoi(audio_info+4); //位置信息的格式是ced=xxx,所以前四个字符被截断抛弃 char text_complete[255]; //声明字符串,“已经合成完毕的文本” strcpy(text_complete ,src_text + pos); //将原字符串复制到新字符串中,并对其前部进行截断,把之前合成的,非本次合成的文本抛弃 text_complete[ced-pos]='\0'; //将新字符串进行后部截断,截断到ced提示的位置,这样这个字符串就是本次获取到的字符串了 printf("[%d]:get result[err==%d / status==%d]:%s\n", (loop_count), ret, synth_status,text_complete); loop_count++; //取结果次数自增 pos = ced; //合成位置更新 /**************获取合成位置结束***************/ if ( ret != MSP_SUCCESS ) { printf("QTTSAudioGet: qtts get audio failed Error code %d.\n",ret); break; } /*********获取当前会话此时的流量信息**********///如果不需要该功能,本段可以删除 value_len = 32;//value_len既是传入参数,又是传出参数,每次调用QTTSGetParam时要调整为buffer长度 ret = QTTSGetParam(sess_id,"upflow",param_value,&value_len);//获取上行流量信息 if ( ret != MSP_SUCCESS ) { printf("QTTSGetParam: qtts get param failed Error code %d.\n",ret); break; } upload_flow = atoi(param_value); printf("upflow== %d Byte\n",upload_flow); value_len = 32;//value_len既是传入参数,又是传出参数,每次调用QTTSGetParam时要调整为buffer长度 ret = QTTSGetParam(sess_id,"downflow",param_value,&value_len);//获取下行流量信息 if ( ret != MSP_SUCCESS ) { printf("QTTSGetParam: qtts get param failed Error code %d.\n",ret); break; } download_flow = atoi(param_value); printf("downflow== %d Byte\n",download_flow); /**************获取流量信息结束***************/ fwrite(audio_data, 1, audio_len, fp); pcmwavhdr.data_size += audio_len;//修正pcm数据的大小 if ( MSP_TTS_FLAG_DATA_END == synth_status ) { printf("QTTSAudioGet: get end of data.\n"); break; } } //修正pcm文件头数据的大小 pcmwavhdr.size_8 += pcmwavhdr.data_size + 36; //将修正过的数据写回文件头部 fseek(fp, 4, 0); fwrite(&pcmwavhdr.size_8,sizeof(pcmwavhdr.size_8), 1, fp); fseek(fp, 40, 0); fwrite(&pcmwavhdr.data_size,sizeof(pcmwavhdr.data_size), 1, fp); fclose(fp); ret = QTTSSessionEnd(sess_id, "Normal"); if ( ret != MSP_SUCCESS ) { printf("QTTSSessionEnd: qtts end failed Error code %d.\n",ret); } return ret; }