




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、基于漢字編碼特性構造函數實現的語音系統日期:2006-05-22來源: 作者:字體:大 中 小 黃紅偉 湯興華 摘要:基于漢字編碼的特性,本文構造了一個函數,利用這個函數為每一個漢字建立索引,基于此建立了一個很小的基于文件形式的語音庫;在程序里調用這個語音庫來達到漢字語音輸出的功能。同時給出了實現此語音庫的方法、步驟及怎樣調用此語音庫,及相應的程序代碼。關鍵詞:漢字編碼,函數,語音系統 1關于漢字映射序號函數 f 首先讓我們來考查一下漢字的編碼(我們這里只研究中國大陸的簡體中文GB2312,下同)。根據ANSI字符集1,每一個漢字由兩個字
2、節構成,由一個十六進制數唯一表示,例如:黃,其十六進制編碼為:0xBBC6。我們可以看到在構成黃字的這兩個字節中,第一個字節表示的值為:0xBB,第二個字節為:0xC6。通過研究Windows系統中的字符映射表,我們可以得出以下命題:命題一在表示簡體中文的這兩個字節中,第一個字節的標識范圍為:0xB00xF7,第二個字節的標識范圍為:0xA10xFE。根據命題一,我們得出:命題二用這兩個字節在此標識范圍之內所能表示的漢字個數為:(0xF70xB01)×(0xFE0xA11)72×946768。事實上字符映射表里的簡體漢字個數也為6768個。于是我們定義了一個函數f:定義一:
3、P = f(Q) = (Q1 0xB0) × 94 + (Q2 0xA1)其中:Q為任一漢字的十六進制編碼,顯然這里Q由兩個字節構成,Q1為構成Q的兩個字節中的第一個字節,Q2為第二個字節,所以:0xB0Q10xF7,0xA1Q20xFEP = p | 0 t 6767 且 p為整數不難證明此函數是可逆的。得出命題三:命題三任意給定一漢字,根據函數f,總可以找到一個唯一的數p (pP),讓p來代表這個漢字,反之,給定一數p(pP),也總有一個唯一的漢字與之對應。于是我們有f(啊) = f(0xB0A1) = 0,又如f(黃) = f(0xBBC6) = 1071,如此等等。
4、;2.關于漢字拼音對照表通過考查新華字典2,我們為字符映射表里的6768個簡體漢字建立了一個漢語拼音對照表。對照表里在每一個拼音的后面加上一個數字,以示聲調,第一聲用1表示,第二聲用2,第三聲用3, 第四聲用4,平聲用5。例如:啊 a1,黃huang2。由于漢字里同音字比較多,所以6768個漢字拼音里實際上不同聲調者只有1317個。 為了準備基本的語音素材,我們特地從電視臺請了一位播音員錄制了這1317個不同的發音。其中每一個發音是一個單獨的wav型文件,其文件名就是其對應的漢語拼音,例如huang2這個音的文件名字就是huang2。3.關于語音庫的建立語音庫分為兩個部份,第一部份存貯6768
5、個漢字中的每一個漢字語音數據在庫中的位置索引,第二部份存貯的是已經錄制好的1317個wav文件的數據。事實上在庫中并沒有存貯漢字本身,因為根據前面得到的命題三,字符映射表里的每一個漢字都有一個唯一的數字與其對應,故這個語音庫的第一部份,也就是索引部份,可以看作一個有6768個元素的數組-SndIdx6768 (實際我們后面編程時也是這樣實現的),例如SndIdx1071的值是黃這個字的語音數據在庫中的位置偏移量。因為1317個語音數據有10M之多,故索引數組的元素值遠超過32767,為此數組的每一個元素占有4個字節的空間。因此索引大小為:4 × 6768 25K 。調用語音庫時利用了
6、兩個緩沖區 :DWORD SndIdx6768 與char *m_szSndBuff,m_szSndBuff = (char *)malloc( 語音庫文件第二部份的大小 )。然后把語音庫文件fsnd.dat的第一部份,也就是索引部份讀入SndIdx;把第二部份,也就是語音數據部份讀入m_szSndBuff。當需要語音輸出的時候,例如要輸出黃的讀音,程序根據定義一的函數f得出與該字對應的的編號為1071,于是得到該字的讀音在緩沖區m_szSndBuff中的偏移量為SndIdx1071,然后調用Windows的用于播放wav數據的API函數來輸出該字的發音:sndPlaySound(
7、 m_szSndBuff + SndIdx1071 , SND_SYNC | SND_MEMORY )3。 4.關于系統的實現首先我們來研究怎樣生成這個語音系統。語音系統的主體部份其實只是一個數據文件fsnd.dat,我們要做的只是怎樣把這些索引與單個的漢字語音數據寫到fsnd.dat中。對于6768個漢字的索引以及1317個不同的語音數據文件,我們構造了一個算法做這件事。為此我們設計了一個臨時數據庫(sndDB),這個庫里只有一張表(wordtable),原型是我們前面整理的漢語拼音對照表,正如我們前面所知,這個表有兩個字段:漢字本身(在表里用 m_Word 表示)與其對應的拼音(
8、在表里用 m_Sound 表示)。根據命題三,每一個漢字都與一個唯一的整數對應,因此6768個漢字在這張表里是按這些整數的從小到大的順序來排列的。另外為了算法的實現,我們又加了兩個額外的字段,一個是:bool m_Tag ,初始化為0,這是一個標志,因為我們知道,漢字里同音字比較多,當對一個拼音對應的語音數據進行處理之后,這個語音數據在fsnd.dat中的偏移量就已確定,那么其它同音的漢字的對應語音數據的偏移量也是同一個值,此時就把這些同音字的這個標志置為1,以后看到這個標志為1就跳到下一漢字。另一個額外的字段是:long m_sndIndex, 顧名思義,就是記錄該漢
9、字語音數據在此文件中的偏移量,初始為0。又因為fsnd.dat是由兩部份構成:索引部份與數據部份,為了方便,將這兩部份分成兩個文件來處理,然后再把包含語音數據的這個文件(totalsnd.dat)的全部內容寫到fsnd.dat的后面。因為我們前面說過索引部份可看作一個數組,故在程序中我們又設計了一個數組:DWORD SndIdx6768,來充當數據庫與fsnd.dat的中轉。以下是具體的程序部份:m_DbSnd.Open( "sndDB", false, false, "ODBC; UID = sa " ); /m_DbSnd為數據庫對象m_pSndSe
10、t = new CSndSet( &m_DbSnd ) ; /m_pSndSet為指向數據集的指針m_pSndSet->Open ();/打開數據集 fsnd.Open( "fsnd.dat", CFile:modeCreate | CFile:modeWrite );/fsnd為一文件對象 DWORD idex = 0 ; /從第一個wav文件到第i個wav文件的長度的累加和
11、60; DWORD sndLen = 0; /記錄第i個wav文件的長度 char pszFilePath50 = "E:myworkhhwwav" /語音文件位于該目錄下 char *pFileKind = ".wav" /語音文件是.wav文件
12、 CFile snd; /代表具體漢字的語音文件對象 Cfile totalsnd( "totalsnd.dat" , CFile:modeCreate | CFile:modeWrite );/全部語音文件數據寫入totalsnd.dat
13、 CString strsnd; /記錄從數據庫里讀出的漢字的漢語拼音 char *sndBuff = NULL; /為第i個wav文件數據開辟緩沖區 int i=0; CString str
14、SQL;/要執行的SQL查詢、更新語句 while( !m_pSndSet->IsEOF() )/從數據庫里的第一條記錄讀到最后一條 if( m_pSndSet->m_tag =
15、 TRUE ) /說明該字與前面某個字同音 SndIdxi
16、 = m_pSndSet->m_sndIndex ; fsnd.Write(&SndIdxi, sizeof(DWORD);/將該字發音數據所在位置寫入文件
17、; i+ ; m_pSndSet->MoveNext
18、(); continue ;
19、60; strsnd = m_pSndSet->m_sound ; strcat( pszFilePath , strsnd );/具體漢字語音數據文件名與其拼音是一致的
20、160; strcat( pszFilePath , pFileKind );/給出該字發音文件的完整路徑 &
21、#160; snd.Open( pszFilePath , CFile:modeRead | CFile:typeBinary ); /打開相應的發音文件
22、 strcpy( pszFilePath, "E:myworkhhwwav" ); /初始化下個漢字發音文件的
23、路徑 /將與該字同音的漢字打上標志,并置發音索引為一樣
24、160; strSQL.Format("update wordtable set m_tag=1,m_sndIndex=%d where m_sound='%s'", idex, strsnd ); m_DbSnd.ExecuteSQL( strSQL
25、 ); SndIdxi = idex ;
26、60; fsnd.Write( &SndIdxi, sizeof(DWORD);/將該字發音數據所在位置寫入文件 i+;
27、160; sndLen = snd.GetLength(); /得到該字發音文件的大小 idex += sndLen ; /緊接的
28、與該漢字不同音的下一漢字的發音在文件中的偏移量 if( sndBuff != NULL ) &
29、#160; free( sndBuff );
30、160; sndBuff = NULL; sndBuff = ( char* )malloc( sndLe
31、n );/為該wav文件數據分配緩沖區 snd.ReadHuge( sndBuff, sndLen ) ; /
32、60; totalsnd.SeekToEnd(); totalsnd.WriteHuge( sndBuff, sndLen);/ 把緩沖區語音數據寫到語音數據文件
33、60; snd.Close();/關閉該讀音的wav文件 m_pSndSet->Move
34、( i ); /轉向下一個漢字 totalsnd.Close();/關閉語音數據文件 /以讀
35、的且二進制的方式打開語音數據文件以把它的數據并到fsnd.dat里去 totalsnd.Open( "totalsnd.dat", CFile:modeRead | CFile:typeBinary ); sndLen = totalsnd.GetLength();
36、; if( sndBuff != NULL ) free( sndBuff );
37、 sndBuff = NULL; sndBuff = ( char* )malloc( sndLen );
38、 totalsnd.ReadHuge( sndBuff , sndLen );/把全部語音數據寫到緩沖區里 totalsnd.Close(); fsnd.WriteHuge( sndBuff , sndLen ); /把全部語音數據寫到索引部份后面 fsnd.Close();/fsnd.
39、dat制作完畢,關閉文件對象 至此這個語音系統的主體部份fsnd.dat已經完成。考慮到這個語音系統只是我們要開發的客戶系統的一個外掛程序,于是把庫文件的調用部份做成一個動態鏈接庫,即一個dll文件。在這個dll文件中輸出了一個類。這個類是這樣定義的:class CTextSnd public: CTextSnd(); virtual CTextSnd();
40、 void Load(); /通過新開的一個線程調用LoadSnd, void UnLoad( void );清空緩沖區數據。
41、160; BOOL LoadSnd();/打開fsnd.dat,載入聲音數據到m_szSndBuff,索引數據到SndIdx6768 BOOL Play( char * szText );/szText是一段需要語音輸出的文字,用Play(char* szText)來完成private: char *
42、; m_szSndBuff; DWORD SndIdx6768; 由于語音輸出功能是在系統處理業務的時候才調用,故語音輸出與這些業務的進行應該是并發的,為此單獨開了一個線程來處理語音輸出,這是一個全程函數:DWORD WINAPI LoadSndT
43、hread(CTextSnd* ptr) ptr->LoadSnd(); return 0; 我們是這樣調用這個全程函數的:void CTextSnd:Load() DWORD ThreadId; CloseHandle(CreateThread(NULL,0,(unsigned long(_stdcall*)(void*)LoadSndThread,
44、this,0,&ThreadId);最后再給出用于最終輸出語音的函數:BOOL CTextSnd:Play(char* szText )。BOOL CTextSnd:Play( char * szText )/szText為一指針,指向要語音輸出的那段話 if( m_szSndBuff = NULL) return FALSE; DWORD dwSndPosition; char * pT = szText; &
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 雙金屬帶鋸條企業縣域市場拓展與下沉戰略研究報告
- 切塊機企業數字化轉型與智慧升級戰略研究報告
- 紫銅箔材企業數字化轉型與智慧升級戰略研究報告
- 袋泡茶企業ESG實踐與創新戰略研究報告
- 雙色印臺企業數字化轉型與智慧升級戰略研究報告
- 加盟烤翅合同標準文本
- 硬化橡膠電氣絕緣子企業ESG實踐與創新戰略研究報告
- 耐熱鋼產品企業ESG實踐與創新戰略研究報告
- 微型氣泵企業縣域市場拓展與下沉戰略研究報告
- 三相載波電能表企業縣域市場拓展與下沉戰略研究報告
- 深入淺出Serverless:技術原理與應用實踐課件
- 公路施工技術高職PPT完整全套教學課件
- 年產十萬噸丙烯腈生產工藝設計
- 人教版高中物理必修二全冊同步課時練習
- 城市社區管理中存在的問題及對策研究正文內容
- 年產10噸功能益生菌凍干粉的工廠設計改
- (完整)人教版 高一物理課后習題答案
- GB/Z 26337.1-2010供應鏈管理第1部分:綜述與基本原理
- GB 150-1998鋼制壓力容器
- 幼兒園繪本:《超級細菌王國》
- 2023年海南省財金集團有限公司招聘筆試模擬試題及答案解析
評論
0/150
提交評論