訊飛C/C++語音合成基礎篇
阿新 • • 發佈:2019-02-20
首先到訊飛上註冊一個帳號(感覺訊飛官網和阿里雲官網的差不多)
隨後建立一個新應用(Windows平臺下)
最後我們要的是Appid如下圖所示
下面是訊飛SDK(含說明文件)下載地址:
因為此程式涉及WAV語音知識,未了解WAV的朋友請百度補充,或者在下面這個連結初略的學習下
下面先來認識下幾個API(從文件提取出來)
1.int MSPAPI MSPLogin (const char *usr, const char *pwd, const char *params)//初始化msc,使用者登入。
usr[in]此引數保留,傳入NULL即可。
pwd[in]此引數保留,傳入NULL即可。
官方例子
const char* usr = NULL;
const char* pwd = NULL;
const char* lgi_param = "appid = ********";
int ret = MSPLogin(usr, pwd, lgi_param);
if( MSP_SUCCESS != ret )
{
printf( "MSPLogin failed, error code is: %d", ret );
}
2.const char *MSPAPI QTTSSessionBegin (const char *params, int *errorCode)//開始一次語音合成,分配語音合成資源。
(資訊有點多,引數具體見文件qtts.h 檔案參考)
下面是官方例子
3.const void *MSPAPI QTTSAudioGet (const char *sessionID, unsigned int *audioLen, int *synthStatus, int *errorCode)//獲取合成音訊const char * ssb_param = "voice_name = xiaoyan, aue = speex-wb;7, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2"; int ret = -1; const char * sessionID = QTTSSessionBegin( ssb_param, &ret ); if( MSP_SUCCESS != ret ) { printf( “QTTSSessionBegin failed, error code is: %d”, ret ); }
(資訊有點多,引數具體見文件qtts.h 檔案參考)
例子
FILE* fp = fopen("tts.pcm", "wb");
while (1)
{
const void * data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);
if (NULL != data)
{
fwrite(data, audio_len, 1, fp);
}
if (MSP_TTS_FLAG_DATA_END == synth_status || MSP_SUCCESS != ret)
{
break;
}
}
fclose(fp);
4.int MSPAPI QTTSSessionEnd (const char *sessionID, const char *hints)//結束本次語音合成。
int ret = QTTSSessionEnd ( sessionID, “normal end” );
if( MSP_SUCCESS != ret )
{
printf( “QTTSSessionEnd failed, error code is: %d”, ret );
}
下面是完整專案的程式碼:
幾個個檔案1.stdafx.h。2.targetver.h。3.QTTSDemo.cpp。4.stdafx.cpp。
除了QTTSDemo.cpp外,其他檔案都是vs2013建立控制檯程式自帶的,在此只給出QTTSDemo.cpp程式碼
但注意在stdafx.h中加入#define _CRT_SECURE_NO_WARNINGS
QTTSDemo.cpp
// QTTSDemo.cpp : 定義控制檯應用程式的入口點。
//
#include "stdafx.h"
#include <msp_cmn.h>
#include <msp_errors.h>
#include <qtts.h>
#include <string.h>
#include <windows.h>
#pragma comment(lib,"WinMM.lib")
#ifdef _WIN64
#pragma comment(lib,"msc_x64.lib")
#else
#pragma comment(lib,"msc.lib")
#endif
//wav音訊頭部格式
typedef struct _wave_pcm_hdr
{
char riff[4]; //="RIFF"
int size_8; //=FileSize=8
char wave[4]; //="WAVE"
char fmt[4]; //="fmt"
int fmt_size; //=下一個結構體的大小:16
short int format_tag; //=PCM:1
short int channels; //=通道數:1
int samples_per_sec; //=取樣率:8000|6000|16000
int avg_bytes_per_sec; //=每秒位元組數:samples_per_sec*bit_per_sample
short int block_align; //=每取樣點位元組數:wBitsPerSample/8
short int bits_per_sample; //=量化位元數:8|16
char data[4]; //="data";
int data_size; //=純資料長度:FileSize-44
}wave_pcm_hdr;
/*預設wav音訊頭部資料*/
wave_pcm_hdr default_wav_hdr =
{
{ 'R', 'I', 'F', 'F' },
0,
{ 'W', 'A', 'V', 'E' },
{ 'f', 'm', 't', ' ' },
16,
1,
1,
16000,
32000,
2,
16,
{ 'd', 'a', 't', 'a' },
0
};
int _tmain(int argc, _TCHAR* argv[])
{
//登入
const char* usr = NULL;
const char* pwd = NULL;
const char* lgi_param = "appid = 583aea17";
int ret = MSPLogin(usr, pwd, lgi_param);
if (MSP_SUCCESS != ret)
{
printf("MSPLogin failed, error code is: %d", ret);
}
//開始合成
const char * ssb_param = "voice_name = xiaorong, aue = speex-wb;7, sample_rate = 16000, speed = 50, volume = 80, pitch = 50, rdn = 2";
ret = -1;
const char * sessionID = QTTSSessionBegin(ssb_param, &ret);
if (MSP_SUCCESS != ret)
{
printf("QTTSSessionBegin failed, error code is : %d", ret);
}
//設定待合成文字
char src_text[1024];
printf("請輸入一段文字(中文注意逗號,句話):\n");
gets(src_text);
unsigned int text_len = strlen(src_text); //textLen引數為合成文字所佔位元組數
ret = QTTSTextPut(sessionID, src_text, text_len, NULL);
if (MSP_SUCCESS != ret)
{
printf("QTTSTextPut failed, error code is : %d", ret);
}
//獲取合成的音訊wav
FILE* fp = fopen("Demo.wav", "wb"); //一定是二進位制模式
fwrite(&default_wav_hdr, sizeof(default_wav_hdr), 1, fp);
unsigned int audio_len = 0;
int synth_status = 0;
while (1)
{
const void * data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret);
if (NULL != data)
{
fwrite(data, audio_len, 1, fp);
default_wav_hdr.data_size += audio_len;
}
if (MSP_TTS_FLAG_DATA_END == synth_status || MSP_SUCCESS != ret)
{
break;
}
}
default_wav_hdr.size_8 += default_wav_hdr.data_size + (sizeof(default_wav_hdr)-8);
fseek(fp, 4, 0);
fwrite(&default_wav_hdr.size_8, sizeof(default_wav_hdr.size_8), 1, fp); //寫入size_8的值
fseek(fp, 40, 0); //將檔案指標偏移到儲存data_size值的位置
fwrite(&default_wav_hdr.data_size, sizeof(default_wav_hdr.data_size), 1, fp);//寫入data_size的值
fclose(fp);
PlaySoundA("Demo.wav", NULL, SND_ASYNC);
ret = QTTSSessionEnd(sessionID, "normal end");
if (MSP_SUCCESS != ret)
{
printf("QTTSSessionEnd failed, error code is : %d", ret);
}
//退出
ret = MSPLogout();
if (MSP_SUCCESS != ret)
{
printf("MSPLogout failed, error code is: %d", ret);
}
system("pause");
return 0;
}