• <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>
            asm, c, c++ are my all
            -- Core In Computer
            posts - 139,  comments - 123,  trackbacks - 0
            [轉]Windows 語音編程初步

            一、SAPI簡介

            軟件中的語音技術包括兩方面的內容,一個是語音識別(speech recognition) 和語音合成(speech synthesis)。這兩個技術都需要語音引擎的支持。微軟推出的應用編程接口API,雖然現在不是業界標準,但是應用比較廣泛。

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

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

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

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

            二、安裝SAPI SDK。

            首先從這個站點下載開發包: http://www.microsoft.com/speech/download/sdk51

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

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

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

            系統要求98以上版本。編譯開發包中的例子程序需要vc6以上環境。

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

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

            三、配置vc環境

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

            四、語音合成的應用。即使用SAPI實現TTS(Text to Speech)。

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

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

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

            2、獲取/設置輸出頻率。

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

            ?? 可以使用如下代碼獲取當前的配置:
            ?? 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 是一個ENUM類型,定義位于SPAI.H中。每一個值對應了不同的頻率設置。例如 SPSF_8kHz8BitStereo? = 5

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

            ??? 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、獲取/設置播放所用語音。

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

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

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

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

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

            5、跳過部分朗讀的文字

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

            6、播放WAV文件。SAPI可以播放WAV文件,這是通過ISpStream接口實現的:

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

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

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

            ?? //創建一個輸出流,綁定到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中提供的函數創建 wav 文件
            ?? if (SUCCEEDED(hr))
            ?? {
            ????? hr = SPBindToFile( m_szWFileName, SPFM_CREATE_ALWAYS, &cpWavStream,
            ???????????????????????? &OriginalFmt.FormatId(), OriginalFmt.WaveFormatExPtr() );
            ??? }
            ?? if( SUCCEEDED( hr ) )
            ?? {
            ????? //設置聲音的輸出到 wav 文件,而不是 speakers
            ????? m_cpVoice->SetOutput(cpWavStream, TRUE);
            ??? }
            ??? //開始朗讀
            ??? m_cpVoice->Speak( szWTextString, SPF_ASYNC | SPF_IS_NOT_XML, 0 );

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

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

            ?? hpos的值一般位于

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

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

            ?? 在窗口響應WM_TTSAPPCUSTOMEVENT消息的函數中,通過如下代碼獲取sapi的通知事件:

            ??? CSpEvent??????? event;? // 使用這個類,比用 SPEVENT結構更方便

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

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

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

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

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

            <2006年7月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            常用鏈接

            留言簿(7)

            隨筆檔案

            最新隨筆

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            成人国内精品久久久久影院VR| 一级女性全黄久久生活片免费 | 久久se精品一区二区| 国产精品久久久久久久久| 久久93精品国产91久久综合| 伊人久久大香线蕉无码麻豆| 久久精品国产亚洲AV高清热| 久久99亚洲综合精品首页| 久久国产免费直播| 精品人妻伦一二三区久久| 无码人妻精品一区二区三区久久| 91精品国产综合久久香蕉| 久久精品国产亚洲AV久| 99久久亚洲综合精品成人| 无码人妻久久一区二区三区免费丨| 香港aa三级久久三级| 亚洲精品无码久久一线| 久久久这里只有精品加勒比| 伊人色综合久久| 欧美伊香蕉久久综合类网站| 欧美va久久久噜噜噜久久| 蜜桃麻豆www久久国产精品| 中文字幕亚洲综合久久| 亚洲级αV无码毛片久久精品| 久久无码人妻精品一区二区三区| .精品久久久麻豆国产精品 | 日本免费一区二区久久人人澡| 亚洲中文字幕久久精品无码APP| 久久午夜综合久久| 久久亚洲国产成人精品无码区| 国产精品99久久不卡| 国产精品99久久久久久董美香| 久久99热国产这有精品| 狠狠色丁香久久综合婷婷| 国产欧美久久久精品| 久久久国产精品福利免费| 日本久久久久久中文字幕| 韩国三级中文字幕hd久久精品 | 97热久久免费频精品99| 好属妞这里只有精品久久| 久久香蕉一级毛片|