一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

【VC++技術(shù)雜談004】使用微軟TTS語音引擎實現(xiàn)文本朗讀

 goodwangLib 2018-05-11

  本文主要介紹如何使用微軟TTS語音引擎實現(xiàn)文本朗讀,以及生成wav格式的聲音文件。

 

1.語音引擎及語音庫的安裝

  TTS(Text-To-Speech)是指文本語音的簡稱,即通過TTS引擎把文本轉(zhuǎn)化為語音輸出。

  微軟TTS語音引擎提供了Windows Speech SDK開發(fā)包供編程者使用。Windows Speech SDK包含語音合成SS引擎和語音識別SR引擎兩種,語音合成引擎用于將文字轉(zhuǎn)換成語音輸出,語音識別引擎用于識別語音命令。

  Windows Speech SDK可以在微軟的官網(wǎng)上免費下載,下載地址為:http://www.microsoft.com/download/en/details.aspx?id=10121

  在該下載界面中,選擇下載SpeechSDK51.exe、SpeechSDK51LangPach.exe和sapi.chm 即可。其中,SpeechSDK51.exe是簡體中文語音引擎,SpeechSDK51LangPach.exe是中文男生語音庫,sapi.chm是SAPI(The Microsoft Speech API)幫助文檔。

  下載完成后,先安裝語音引擎SpeechSDK51.exe,再安裝中文語音庫SpeechSDK51LangPach.exe。安裝完成后,可以依次點擊【開始】/【控制面板】/【語言】打開圖1所示的語言屬性對話框。在該對話框的“文字-語音轉(zhuǎn)換”標(biāo)簽頁下的“語音選擇”中能夠看到當(dāng)前系統(tǒng)安裝的全部可用的語音庫。

圖1 語言屬性對話框

 

2.ISpVoice接口的成員函數(shù)

  文本朗讀的功能主要是通過使用ISpVoice接口的成員函數(shù)來實現(xiàn)的。該接口的常用成員函數(shù)有如下一些:

(1)HRESULT Speak(LPCWSTR *pwcs, DWORD dwFlags, ULONG *pulStreamNumber);  //朗讀文本

(2)HRESULT Pause ( void);                                   //暫停朗讀

(3)HRESULT Resume ( void);                                //恢復(fù)朗讀 

(4)HRESULT SetRate( long RateAdjust);                 //設(shè)置朗讀速度(取值范圍:-10到10)

(5)HRESULT GetRate(long *pRateAdjust);              //獲取朗讀速度

(6)HRESULT SetVoice(ISpObjectToken   *pToken);      //設(shè)置使用的語音庫

(7)HRESULT GetVoice(ISpObjectToken** ppToken);    //獲取語音庫

(8)HRESULT SetVolume(USHORT usVolume);          //設(shè)置音量(取值范圍:0到100)

(9)HRESULT GetVolume(USHORT *pusVolume);      //獲取音量

(10)HRESULT SetOutput(IUnknown *pUnkOutput,BOOL fAllowFormatChanges);     //設(shè)置輸出

(11)HRESULT SpeakStream(IStream *pStream, DWORD dwFlags, ULONG *pulStreamNumber);   //朗讀wav數(shù)據(jù)流

 

3.編程實例

  了解了以上一些ISpVoice接口的成員函數(shù)之后,我們就可以開始編寫程序來實現(xiàn)文本朗讀,以及生成wav格式聲音文件的功能了。

3.1環(huán)境配置

  首先,我們需要將Windows Speech SDK開發(fā)包的頭文件和庫文件所在路徑添加到編譯器中,具體方法如下(這里以VC++6.0為例):

  依次點擊【工具】/【選項】,打開選項對話框,選擇【目錄】標(biāo)簽,在【路徑】中加入“C:\Program Files\Microsoft Speech SDK 5.1\Include”和“C:\Program Files\Microsoft Speech SDK 5.1\Lib\i386”。如圖2所示。

圖2 選項對話框

  其次,還需要在工程中包含TTS語音引擎頭文件和庫文件,具體如下:

1 #include <sapi.h>                            //包含TTS語音引擎頭文件和庫文件
2 #include <sphelper.h>
3 #pragma comment(lib, "sapi.lib")

3.2枚舉語音庫

  枚舉語音庫需要使用到SpEnumTokens()函數(shù),該函數(shù)原型如下:

1 inline HRESULT SpEnumTokens(
2    const WCHAR            *pszCategoryId,
3    const WCHAR            *pszReqAttribs,
4    const WCHAR            *pszOptAttribs,
5    IEnumSpObjectTokens   **ppEnum
6 );

  其中,參數(shù)ppEnum是IEnumSpObjectTokens類型的指針,用于存儲枚舉得到的所有語音Token。IEnumSpObjectTokens的成員函數(shù)GetCount()用于得到語音Token的總個數(shù),而成員函數(shù)Item()則用于得到具體的某一個語音Token

  如下的代碼示例如何枚舉得到的所有語音Token,并將得到的語音庫的名字添加到下拉組合框控件中,具體實現(xiàn)如下:

復(fù)制代碼
 1 /*
 2  * 函數(shù)功能 : 初始化語言包選擇組合框控件
 3  * 備    注 : 
 4  * 作    者 : 博客園 依舊淡然
 5  */
 6 void CTTSDemoDlg::InitVoicePackageSelComboxCtrl()
 7 {
 8     //初始化COM組件
 9     if(FAILED(::CoInitialize(NULL)))
10     {
11         MessageBox("初始化COM組件失敗!", "提示", MB_OK|MB_ICONWARNING);
12         return;
13     }
14 
15     //枚舉所有語音Token
16     if(SUCCEEDED(SpEnumTokens(SPCAT_VOICES, NULL, NULL, &m_pIEnumSpObjectTokens)))
17     {
18         //得到所有語音Token的個數(shù)
19         ULONG ulTokensNumber = 0;
20         m_pIEnumSpObjectTokens->GetCount(&ulTokensNumber);
21         
22         //檢測該機器是否安裝有語音包
23         if(ulTokensNumber == 0)
24         {
25             MessageBox("該機器沒有安裝語音包!", "提示", MB_OK|MB_ICONWARNING);
26             return;    
27         }
28         
29         //將語音包的名字加入組合框控件
30         CString strVoicePackageName = _T("");
31         CString strTokenPrefixText = _T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\");
32         for(ULONG i=0; i<ulTokensNumber; i++)
33         {
34             m_pIEnumSpObjectTokens->Item(i, &m_pISpObjectToken);
35             WCHAR* pChar;
36             m_pISpObjectToken->GetId(&pChar);
37             strVoicePackageName = pChar;
38             strVoicePackageName.Delete(0, strTokenPrefixText.GetLength());
39             m_ComboxVoiceSel.InsertString(i, strVoicePackageName);
40         }
41 
42         //設(shè)置默認的語音包選擇
43         m_ComboxVoiceSel.SetCurSel(0);
44     }
45 }
復(fù)制代碼

  通過以上的代碼可以看到,首先,我們通過調(diào)用CoInitialize()函數(shù)完成了對COM組件的初始化。然后,我們調(diào)用SpEnumTokens()函數(shù)得到了m_pIEnumSpObjectTokens對象,該對象存儲了枚舉得到的所有語音Token。緊接著,我們調(diào)用GetCount()函數(shù)得到個數(shù),并調(diào)用Item()函數(shù)得到具體的每一個語音Token對象m_pISpObjectToken。最后,我們通過調(diào)用m_pISpObjectToken對象的GetId()函數(shù)便能得到具體的某一個Token對象的ID,其形式為“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\XXXXX”,去掉其前綴便能得到具體的語音庫的名字了。

  該實例運行效果如圖3所示,點擊“語音包選擇”組合框下拉箭頭,能夠看到與圖1中列出的語音包是一致的。

圖3 TTS示例運行效果

3.3文本朗讀

  點擊圖3所示界面中的“開始朗讀”按鈕,能夠根據(jù)當(dāng)前所選擇的語音包以及設(shè)定的語速和音量,對朗讀內(nèi)容編輯框中的內(nèi)容進行朗讀。其具體實現(xiàn)方法如下:

復(fù)制代碼
 1 /*
 2  * 函數(shù)功能 : 點擊"開始朗讀"按鈕時,該函數(shù)被調(diào)用
 3  * 備    注 : 
 4  * 作    者 : 博客園 依舊淡然
 5  */
 6 void CTTSDemoDlg::OnButtonStartRead() 
 7 {
 8     UpdateData(true);
 9 
10     //獲取ISpVoice接口
11     if(FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void**)&m_pISpVoice)))
12     {
13         MessageBox("獲取ISpVoice接口失敗!", "提示", MB_OK|MB_ICONWARNING);
14         return;
15     }
16 
17     //設(shè)置語言
18     m_pIEnumSpObjectTokens->Item(m_ComboxVoiceSel.GetCurSel(), &m_pISpObjectToken);
19     m_pISpVoice->SetVoice(m_pISpObjectToken);
20 
21     //設(shè)置播放速度
22     m_pISpVoice->SetRate(m_SliderVoiceSpeed.GetPos() - 10);
23 
24     //設(shè)置音量大小
25     m_pISpVoice->SetVolume(100 - m_SliderVoiceSize.GetPos());
26 
27     //檢測朗讀內(nèi)容是否為空
28     if(m_EditContent.IsEmpty())
29     {
30         MessageBox("朗讀內(nèi)容不能為空!", "提示", MB_OK|MB_ICONWARNING);
31         return;
32     }
33     
34     //開始進行朗讀
35     m_pISpVoice->Speak(m_EditContent.AllocSysString(), SPF_ASYNC, NULL);
36 }
復(fù)制代碼

  在以上代碼中可以看到,使用了ISpVoice接口函數(shù)來完成語音庫的選擇、語速和音量大小的設(shè)定,以及通過調(diào)用Speak()函數(shù)進行文本朗讀。

3.4生成WAV格式的聲音文件

  要將文本朗讀的聲音保存為WAV格式的聲音文件,主要是通過調(diào)用ISpVoice接口函數(shù)GetOutputStream()和SetOutput()來實現(xiàn)的。

以下的代碼段給出了實現(xiàn)該功能的示例:

復(fù)制代碼
 1     //生成WAV文件
 2     CComPtr<ISpStream> cpISpStream;
 3     CComPtr<ISpStreamFormat> cpISpStreamFormat;
 4     CSpStreamFormat spStreamFormat;
 5     m_pISpVoice->GetOutputStream(&cpISpStreamFormat);
 6     spStreamFormat.AssignFormat(cpISpStreamFormat);
 7     HRESULT hResult = SPBindToFile("C:\\Documents and Settings\\Administrator\\桌面\\TEST\\test.wav", 
 8         SPFM_CREATE_ALWAYS, 
 9         &cpISpStream, 
10         &spStreamFormat.FormatId(), 
11         spStreamFormat.WaveFormatExPtr());
12     if(SUCCEEDED(hResult))
13     {
14         m_pISpVoice->SetOutput(cpISpStream, TRUE);
15         m_pISpVoice->Speak(m_EditContent.AllocSysString(), SPF_DEFAULT, NULL);
16         MessageBox("生成WAV文件成功!", "提示", MB_OK);
17     }
18     else
19     {
20         MessageBox("生成WAV文件失敗!", "提示", MB_OK|MB_ICONWARNING);
21     }
復(fù)制代碼

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    五月激情婷婷丁香六月网| 亚洲伦理中文字幕在线观看| 国产原创中文av在线播放| 日本亚洲欧美男人的天堂| 日本人妻的诱惑在线观看| 日韩中文字幕人妻精品| 国产精品久久三级精品| 高中女厕偷拍一区二区三区| 成年午夜在线免费视频| 国产老熟女乱子人伦视频| 二区久久久国产av色| 丝袜破了有美女肉体免费观看| 日本午夜一本久久久综合| 亚洲伦理中文字幕在线观看| 国产自拍欧美日韩在线观看| 日本理论片午夜在线观看| 国产午夜精品在线免费看| 欧美日韩精品久久亚洲区熟妇人 | 欧洲精品一区二区三区四区| 亚洲精品福利视频在线观看| 国产成人免费激情视频| 国产成人精品在线播放| 日韩视频在线观看成人| 日韩欧美一区二区黄色| 日韩欧美二区中文字幕| 老司机精品国产在线视频| 亚洲一级二级三级精品| 欧美一区二区三区性视频 | 日本午夜免费啪视频在线| 欧美久久一区二区精品| 91久久精品国产一区蜜臀| 亚洲天堂精品一区二区| 91精品国产综合久久不卡| 欧美性欧美一区二区三区| 久久女同精品一区二区| 国产精品不卡一区二区三区四区| 日韩国产欧美中文字幕| 亚洲精品一区二区三区免| 人妻一区二区三区在线| 搡老妇女老熟女一区二区| 色老汉在线视频免费亚欧|