青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

asm, c, c++ are my all
-- Core In Computer
posts - 139,  comments - 123,  trackbacks - 0
[轉(zhuǎn)]Windows 語音編程初步

一、SAPI簡介

軟件中的語音技術(shù)包括兩方面的內(nèi)容,一個(gè)是語音識(shí)別(speech recognition) 和語音合成(speech synthesis)。這兩個(gè)技術(shù)都需要語音引擎的支持。微軟推出的應(yīng)用編程接口API,雖然現(xiàn)在不是業(yè)界標(biāo)準(zhǔn),但是應(yīng)用比較廣泛。

SAPI全稱 The Microsoft Speech API.相關(guān)的SR和SS引擎位于Speech SDK開發(fā)包中。這個(gè)語音引擎支持多種語言的識(shí)別和朗讀,包括英文、中文、日文等。

SAPI包括以下組件對象(接口):

(1)Voice Commands API。對應(yīng)用程序進(jìn)行控制,一般用于語音識(shí)別系統(tǒng)中。識(shí)別某個(gè)命令后,會(huì)調(diào)用相關(guān)接口是應(yīng)用程序完成對應(yīng)的功能。如果程序想實(shí)現(xiàn)語音控制,必須使用此組對象。
(2)Voice Dictation API。聽寫輸入,即語音識(shí)別接口。
(3)Voice Text API。完成從文字到語音的轉(zhuǎn)換,即語音合成。
(4)Voice Telephone API。語音識(shí)別和語音合成綜合運(yùn)用到電話系統(tǒng)之上,利用此接口可以建立一個(gè)電話應(yīng)答系統(tǒng),甚至可以通過電話控制計(jì)算機(jī)。
(5)Audio Objects API。封裝了計(jì)算機(jī)發(fā)音系統(tǒng)。

SAPI是架構(gòu)在COM基礎(chǔ)上的,微軟還提供了ActiveX控件,所以不僅可用于一般的windows程序,還可以用于網(wǎng)頁、VBA甚至EXCEL的圖表中。如果對COM感到陌生,還可以使用微軟的C++ WRAPPERS,它用C++類封裝了語音SDK COM對象。

二、安裝SAPI SDK。

首先從這個(gè)站點(diǎn)下載開發(fā)包: http://www.microsoft.com/speech/download/sdk51

Microsoft Speech SDK 5.1添加了Automation支持。所以可以在VB,ECMAScript等支持Automation的語言中使用。

版本說明:
Version: 5.1
發(fā)布日期: 8/8/2001
語音: English
下載尺寸: 2.0 MB - 288.8 MB

這個(gè)SDK開發(fā)包還包括了可以隨便發(fā)布的英文和中文的語音合成引擎(TTS),和英文、中文、日文的語音識(shí)別引擎(SR)。

系統(tǒng)要求98以上版本。編譯開發(fā)包中的例子程序需要vc6以上環(huán)境。

******下載說明******:
(1)如果要下載例子程序,說明文檔,SAPI以及用于開發(fā)的美國英語語音引擎,需要下載SpeechSDK51.exe,大約68M。
(2)如果想要使用簡體中文和日文的語音引擎,需要下載SpeechSDK51LangPack.exe。大約82M。
(3)如果想要和自己的軟件一起發(fā)布語音引擎,需要下載SpeechSDK51MSM.exe,大約132M。
???? (在這個(gè)地址,我未能成功下載)。
(4)如果要獲取XP下的 Mike 和 Mary 語音,下載Sp5TTIntXP.exe。大約3.5M。
(5)如果要獲取開發(fā)包的文檔說明,請下載sapi.chm。大約2.3M。這個(gè)在sdk51里面已經(jīng)包含。

下載完畢后,首先安裝SpeechSDK51.exe,然后安裝中文語言補(bǔ)丁包SpeechSDK51LangPack,然后展開
msttss22l,自動(dòng)將所需dll安裝到系統(tǒng)目錄。

三、配置vc環(huán)境

在vc6.0的環(huán)境下編譯語音工程,首先要配置編譯環(huán)境。假設(shè)sdk安裝在d:\Microsoft Speech SDK 5.1\路徑下,打開工程設(shè)置對話框,在c/c++欄中選擇Preprocessor分類,然后在"附加包含路徑"中輸入
d:\Microsoft Speech SDK 5.1\include
告訴vc編譯程序所需的SAPI頭文件的位置。
然后切換到LINK欄,在Input分類下的附加庫路徑中輸入:
d:\Microsoft Speech SDK 5.1\lib\i386
使vc在鏈接的時(shí)候能夠找到sapi.lib。

四、語音合成的應(yīng)用。即使用SAPI實(shí)現(xiàn)TTS(Text to Speech)。

1、首先要初始化語音接口,一般有兩種方式:
?? ISpVoice* pVoice;
?? ::CoInitialize(NULL);
?? HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice,
?????????????? (void **)&pVoice);
?? 然后就可以使用這個(gè)指針調(diào)用SAPI函數(shù)了,例如
?? pVoice->SetVolume(50);//設(shè)置音量
?? pVoice->Speak(str.AllocSysString(),SPF_ASYNC,NULL);

?? 另外也可以使用如下方式:
??? CComPtr<ISpVoice>?? m_cpVoice;
??? HRESULT? hr = m_cpVoice.CoCreateInstance( CLSID_SpVoice );
?? 在下面的例子中都用這個(gè)m_cpVoice變量。

?? CLSID_SpVoice的定義位于SPAI.H中。

2、獲取/設(shè)置輸出頻率。

?? SAPI朗讀文字的時(shí)候,可以采用多種頻率方式輸出聲音,比如:
?? 8kHz 8Bit Mono、8kHz 8Bit Stereo、44kHz 16Bit Mono、44kHz 16Bit Stereo等。在音調(diào)上有所差別。具體可以參考sapi.h。

?? 可以使用如下代碼獲取當(dāng)前的配置:
?? CComPtr<ISpStreamFormat> cpStream;
?? HRESULT hrOutputStream = m_cpVoice->GetOutputStream(&cpStream);
?? if (hrOutputStream == S_OK)
?? {
?????? CSpStreamFormat Fmt;
?????? hr = Fmt.AssignFormat(cpStream);
?????? if (SUCCEEDED(hr))
?????? {
?????????? SPSTREAMFORMAT eFmt = Fmt.ComputeFormatEnum();
?????? }
?? }
??? SPSTREAMFORMAT 是一個(gè)ENUM類型,定義位于SPAI.H中。每一個(gè)值對應(yīng)了不同的頻率設(shè)置。例如 SPSF_8kHz8BitStereo? = 5

??? 通過如下代碼設(shè)置當(dāng)前朗讀頻率:
??? CComPtr<ISpAudio>?? m_cpOutAudio; //聲音輸出接口
??? SpCreateDefaultObjectFromCategoryId( SPCAT_AUDIOOUT, &m_cpOutAudio ); //創(chuàng)建接口

??? SPSTREAMFORMAT eFmt = 21; //SPSF_22kHz 8Bit Stereo

??? CSpStreamFormat Fmt;
??? Fmt.AssignFormat(eFmt);
??? if ( m_cpOutAudio )
??? {
?hr = m_cpOutAudio->SetFormat( Fmt.FormatId(), Fmt.WaveFormatExPtr() );
??? }
??? else? hr = E_FAIL;

??? if( SUCCEEDED( hr ) )
?? {
?????? m_cpVoice->SetOutput( m_cpOutAudio, FALSE );
?? }

3、獲取/設(shè)置播放所用語音。

?? 引擎中所用的語音數(shù)據(jù)文件一般保存在SpeechEngines下的spd或者vce文件中。安裝sdk后,在注冊表中保存了可用的語音,比如英文的男/女,簡體中文的男音等。位置是:
?? HKEY_LOCAL_MACHINE\Software\Microsoft\Speech\Voices\Tokens
如果安裝在中文操作系統(tǒng)下,則缺省所用的朗讀語音是簡體中文。SAPI的缺點(diǎn)是不能支持中英文混讀,在朗讀中文的時(shí)候,遇到英文,只能逐個(gè)字母讀出。所以需要程序自己進(jìn)行語音切換。

(1) 可以采用如下的函數(shù)把當(dāng)前SDK支持的語音填充在一個(gè)組合框中:
??? // SAPI5 helper function in sphelper.h
??? HWND hWndCombo = GetDlgItem( hWnd, IDC_COMBO_VOICES ); //組合框句柄
??? HRESULT hr = SpInitTokenComboBox( hWndCombo , SPCAT_VOICES );
??? 這個(gè)函數(shù)是通過IEnumSpObjectTokens接口枚舉當(dāng)前可用的語音接口,把接口的說明文字添加到組合框中,并且把接口的指針作為LPARAM
??? 保存在組合框中。
??? 一定要記住最后程序退出的時(shí)候,釋放組合框中保存的接口:
??? SpDestroyTokenComboBox( hWndCombo );
??? 這個(gè)函數(shù)的原理就是逐個(gè)取得combo里面每一項(xiàng)的LPARAM數(shù)據(jù),轉(zhuǎn)換成IUnknown接口指針,然后調(diào)用Release函數(shù)。
(2) 當(dāng)組合框選擇變化的時(shí)候,可以用下面的函數(shù)獲取用戶選擇的語音:
??? ISpObjectToken* pToken = SpGetCurSelComboBoxToken( hWndCombo );

(3) 用下面的函數(shù)獲取當(dāng)前正在使用的語音:
??? CComPtr<ISpObjectToken> pOldToken;
??? HRESULT hr = m_cpVoice->GetVoice( &pOldToken );
(4) 當(dāng)用戶選擇的語音和當(dāng)前正在使用的不一致的時(shí)候,用下面的函數(shù)修改:
??? if (pOldToken != pToken)
??? {???????
???????? // 首先結(jié)束當(dāng)前的朗讀,這個(gè)不是必須的。
???????? HRESULT hr = m_cpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0);
???????? if (SUCCEEDED (hr) )
??????? {
??????????? hr = m_cpVoice->SetVoice( pToken );
???????? }
??? }
(5) 也可以直接使用函數(shù)SpGetTokenFromId獲取指定voice的Token指針,例如:
????? WCHAR pszTokenId[] = L"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Speech\\Voices\\Tokens\\MSSimplifiedChineseVoice";
??? SpGetTokenFromId(pszTokenID , &pChineseToken);

4、開始/暫停/恢復(fù)/結(jié)束當(dāng)前的朗讀
??
?? 要朗讀的文字必須位于寬字符串中,假設(shè)位于szWTextString中,則:
?? 開始朗讀的代碼:
?? hr = m_cpVoice->Speak( szWTextString, SPF_ASYNC | SPF_IS_NOT_XML, 0 );
?? 如果要解讀一個(gè)XML文本,用:
?? hr = m_cpVoice->Speak( szWTextString, SPF_ASYNC | SPF_IS_XML, 0 );

?? 暫停的代碼:?? m_cpVoice->Pause();
?? 恢復(fù)的代碼:?? m_cpVoice->Resume();
?? 結(jié)束的代碼:(上面的例子中已經(jīng)給出了)
?? hr = m_cpVoice->Speak( NULL, SPF_PURGEBEFORESPEAK, 0);

5、跳過部分朗讀的文字

?? 在朗讀的過程中,可以跳過部分文字繼續(xù)后面的朗讀,代碼如下:
?? ULONG ulGarbage = 0;
?? WCHAR szGarbage[] = L"Sentence";
?? hr = m_cpVoice->Skip( szGarbage, SkipNum, &ulGarbage );
?? SkipNum是設(shè)置要跳過的句子數(shù)量,值可以是正/負(fù)。
?? 根據(jù)sdk的說明,目前SAPI僅僅支持SENTENCE這個(gè)類型。SAPI是通過標(biāo)點(diǎn)符號(hào)來區(qū)分句子的。

6、播放WAV文件。SAPI可以播放WAV文件,這是通過ISpStream接口實(shí)現(xiàn)的:

?? CComPtr<ISpStream>?????? cpWavStream;
?? WCHAR??????????????????? szwWavFileName[NORM_SIZE] = L"";;

?? USES_CONVERSION;
?? wcscpy( szwWavFileName, T2W( szAFileName ) );//從ANSI將WAV文件的名字轉(zhuǎn)換成寬字符串

?? //使用sphelper.h 提供的這個(gè)函數(shù)打開 wav 文件,并得到一個(gè) IStream 指針
?? hr = SPBindToFile( szwWavFileName, SPFM_OPEN_READONLY, &cpWavStream );
?? if( SUCCEEDED( hr ) )
?? {
??????? m_cpVoice->SpeakStream( cpWavStream, SPF_ASYNC, NULL );//播放WAV文件
?? }
7、將朗讀的結(jié)果保存到wav文件
?? TCHAR szFileName[256];//假設(shè)這里面保存著目標(biāo)文件的路徑
?? USES_CONVERSION;
?? WCHAR m_szWFileName[MAX_FILE_PATH];
?? wcscpy( m_szWFileName, T2W(szFileName) );//轉(zhuǎn)換成寬字符串

?? //創(chuàng)建一個(gè)輸出流,綁定到wav文件
?? CSpStreamFormat OriginalFmt;
?? CComPtr<ISpStream>? cpWavStream;
?? CComPtr<ISpStreamFormat>??? cpOldStream;
?? HRESULT hr = m_cpVoice->GetOutputStream( &cpOldStream );
?? if (hr == S_OK) hr = OriginalFmt.AssignFormat(cpOldStream);
?? else? hr = E_FAIL;
?? // 使用sphelper.h中提供的函數(shù)創(chuàng)建 wav 文件
?? if (SUCCEEDED(hr))
?? {
????? hr = SPBindToFile( m_szWFileName, SPFM_CREATE_ALWAYS, &cpWavStream,
???????????????????????? &OriginalFmt.FormatId(), OriginalFmt.WaveFormatExPtr() );
??? }
?? if( SUCCEEDED( hr ) )
?? {
????? //設(shè)置聲音的輸出到 wav 文件,而不是 speakers
????? m_cpVoice->SetOutput(cpWavStream, TRUE);
??? }
??? //開始朗讀
??? m_cpVoice->Speak( szWTextString, SPF_ASYNC | SPF_IS_NOT_XML, 0 );

??? //等待朗讀結(jié)束
??? m_cpVoice->WaitUntilDone( INFINITE );
??? cpWavStream.Release();

??? //把輸出重新定位到原來的流
??? m_cpVoice->SetOutput( cpOldStream, FALSE );
???
8、設(shè)置朗讀音量和速度
?? m_cpVoice->SetVolume((USHORT)hpos); //設(shè)置音量,范圍是 0 - 100
?? m_cpVoice->SetRate(hpos);??//設(shè)置速度,范圍是 -10 - 10

?? hpos的值一般位于

9、設(shè)置SAPI通知消息。SAPI在朗讀的過程中,會(huì)給指定窗口發(fā)送消息,窗口收到消息后,可以主動(dòng)獲取SAPI的事件,
?? 根據(jù)事件的不同,用戶可以得到當(dāng)前SAPI的一些信息,比如正在朗讀的單詞的位置,當(dāng)前的朗讀口型值(用于顯
?? 示動(dòng)畫口型,中文語音的情況下并不提供這個(gè)事件)等等。

?? 要獲取SAPI的通知,首先要注冊一個(gè)消息:
?? m_cpVoice->SetNotifyWindowMessage( hWnd, WM_TTSAPPCUSTOMEVENT, 0, 0 );
?? 這個(gè)代碼一般是在主窗口初始化的時(shí)候調(diào)用,hWnd是主窗口(或者接收消息的窗口)句柄。WM_TTSAPPCUSTOMEVENT
?? 是用戶自定義消息。

?? 在窗口響應(yīng)WM_TTSAPPCUSTOMEVENT消息的函數(shù)中,通過如下代碼獲取sapi的通知事件:

??? CSpEvent??????? event;? // 使用這個(gè)類,比用 SPEVENT結(jié)構(gòu)更方便

??? while( event.GetFrom(m_cpVoice) == S_OK )
??? {
??????? switch( event.eEventId )
??????? {
?????????? 。。。
??????? }
??? }

?? eEventID有很多種,比如SPEI_START_INPUT_STREAM表示開始朗讀,SPEI_END_INPUT_STREAM表示朗讀結(jié)束等。
?? 可以根據(jù)需要進(jìn)行判斷使用。

四、結(jié)束語
??
?? SAPI的功能很多,比如語音識(shí)別、使用語法分析等,由于條件和精力有限,我未能一一嘗試,感興趣的朋友可以自己安裝一個(gè)研究一下。
?? 另外提供一個(gè)簡單例子程序的下載,位置是:
??
ftp://vckbase:vckbase@210.192.111.117/user/iwaswzq/Universe.rar

posted on 2006-09-13 00:45 Jerry Cat 閱讀(3444) 評論(1)  編輯 收藏 引用

FeedBack:
# re: Windows 語音編程初步
2007-06-27 15:48 | 老土人
先頂一下,想聯(lián)系一下文章作者,偶的MSN是:oldbumpkin@hotmail.com
偶的電話是:13611138413  回復(fù)  更多評論
  

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理



<2006年9月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用鏈接

留言簿(7)

隨筆檔案

最新隨筆

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美福利一区二区| 亚洲色图自拍| 欧美激情一区二区在线| 久久精品一区二区三区不卡牛牛 | 亚洲欧美国产视频| 亚洲欧美成人一区二区在线电影 | 国产一区 二区 三区一级| 国产日韩欧美二区| 亚洲国产精品视频| 在线亚洲免费| 久久久精彩视频| 亚洲福利在线看| 99精品视频免费在线观看| 亚洲综合精品自拍| 美日韩精品视频| 国产精品久久久久久久午夜| 国产人久久人人人人爽| 在线日韩av| 亚洲一级免费视频| 久久精品一区| 亚洲精品乱码| 欧美一级二区| 欧美激情一区二区三区高清视频| 欧美日韩中文字幕| 黄色欧美成人| 亚洲香蕉伊综合在人在线视看| 欧美影院成人| 最新国产成人在线观看| 性xx色xx综合久久久xx| 欧美阿v一级看视频| 国产日产精品一区二区三区四区的观看方式| 亚洲永久精品大片| 午夜视频一区| 亚洲国产精品视频| 欧美有码视频| 国产精品一区免费视频| 亚洲欧洲综合另类| 另类尿喷潮videofree | 一本不卡影院| 久久精品一本久久99精品| 亚洲精品五月天| 久热精品视频| 狠狠色狠狠色综合日日小说| 亚洲在线视频一区| 亚洲老板91色精品久久| 免费成人你懂的| 在线欧美福利| 老色批av在线精品| 香蕉国产精品偷在线观看不卡 | 亚洲成色精品| 久久久水蜜桃| 香蕉乱码成人久久天堂爱免费| 欧美日韩另类视频| 一本色道久久综合| 亚洲国产精品久久久久秋霞影院| 久久精品中文| 亚洲高清在线观看| 裸体一区二区三区| 久久久久一区二区三区| 精品成人一区二区| 蜜桃av综合| 麻豆国产精品777777在线| 黑人操亚洲美女惩罚| 久久免费99精品久久久久久| 久久激情中文| 激情av一区| 欧美激情在线观看| 欧美国产日韩在线| 夜夜爽99久久国产综合精品女不卡 | 欧美激情bt| 欧美成人资源网| 亚洲精品视频免费在线观看| 亚洲精品1区2区| 欧美午夜精品电影| 久久av一区二区| 裸体一区二区三区| 一区二区三区四区精品| 在线一区二区三区四区| 国产欧美精品一区二区色综合| 久久久久久九九九九| 蜜臀av在线播放一区二区三区| 亚洲另类自拍| 亚洲欧美高清| 亚洲精品美女久久7777777| 99视频热这里只有精品免费| 国产美女精品视频| 欧美激情一区在线观看| 国产精品www网站| 久久婷婷色综合| 欧美日本在线| 久久久亚洲人| 欧美日韩国产bt| 久久免费视频在线| 欧美日韩1234| 国产一二三精品| 亚洲激情在线激情| av不卡在线观看| 国产综合精品| 亚洲毛片av| 在线电影一区| 亚洲欧美日韩一区二区| 亚洲精品一区二区三| 亚洲欧美在线磁力| 夜夜嗨av一区二区三区四区 | 午夜国产不卡在线观看视频| 卡通动漫国产精品| 欧美一区久久| 欧美色大人视频| 欧美岛国激情| 国产区精品在线观看| 最新中文字幕亚洲| 国产一区二区三区黄| 亚洲天堂av图片| 亚洲伦理在线观看| 久久久亚洲成人| 欧美亚洲系列| 欧美午夜视频网站| 最新热久久免费视频| 亚洲第一精品在线| 久久久久久一区二区| 欧美一二三视频| 国产精品v日韩精品v欧美精品网站| 欧美二区在线看| 在线观看日产精品| 久久精品欧美日韩| 久久精品国产视频| 国产精品亚洲а∨天堂免在线| 夜夜精品视频一区二区| 日韩午夜av电影| 欧美国产日韩一区二区在线观看| 免费亚洲电影在线观看| 激情欧美丁香| 久久国产婷婷国产香蕉| 欧美一区二区三区视频在线观看 | 国产精品视频观看| 亚洲深夜福利视频| 亚洲欧美日韩一区在线观看| 欧美视频一区二区| 亚洲视频免费在线| 午夜亚洲视频| 国产日韩精品在线观看| 欧美亚洲视频| 免费欧美在线| 亚洲精品黄色| 欧美日韩国产综合新一区| 亚洲毛片在线免费观看| 亚洲一区免费视频| 国产精品日韩一区| 香蕉av777xxx色综合一区| 久久久亚洲午夜电影| 亚洲国产一区视频| 欧美日韩福利在线观看| 亚洲自拍16p| 美女精品国产| 日韩小视频在线观看| 欧美无砖砖区免费| 欧美在线播放| 亚洲国产一区二区三区青草影视 | 欧美日韩国产高清| 亚洲精品国产精品国自产观看| 亚洲欧洲在线免费| 欧美日韩国产首页在线观看| 一区二区三区视频在线| 性欧美xxxx大乳国产app| 国产午夜亚洲精品不卡| 猫咪成人在线观看| 一本大道av伊人久久综合| 久久国产精品久久久久久| 亚洲福利视频一区二区| 欧美人妖在线观看| 性欧美在线看片a免费观看| 欧美成人黄色小视频| 亚洲一区二区三区成人在线视频精品| 国产欧美日韩在线播放| 你懂的亚洲视频| 亚洲一区二区三区免费在线观看 | 国产精品久久国产三级国电话系列 | 欧美一区二区三区男人的天堂| 激情视频一区二区| 国产精品s色| 老鸭窝毛片一区二区三区| 一区二区三区日韩欧美精品| 麻豆精品国产91久久久久久| 在线视频日本亚洲性| 一区二区视频欧美| 国产精品美女久久| 欧美激情第10页| 久久久久综合网| 亚洲一区二区三区在线播放| 亚洲第一网站| 久久综合综合久久综合| 亚洲欧美亚洲| 99精品国产热久久91蜜凸| 伊人男人综合视频网| 国产欧美日韩一区二区三区在线| 欧美另类一区| 欧美成人中文字幕| 乱码第一页成人| 久久久久国色av免费观看性色| 亚洲一区二区三区四区中文|