- 1、本文档共8页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
基于汉字编码特性构造函数实现的语音系统
[日期:2006-05-22] 来源:? 作者: [字体:大 中 小] 黄红伟 ?汤兴华
?
?
摘要:基于汉字编码的特性,本文构造了一个函数,利用这个函数为每一个汉字建立索引,基于此建立了一个很小的基于文件形式的语音库;在程序里调用这个语音库来达到汉字语音输出的功能。同时给出了实现此语音库的方法、步骤及怎样调用此语音库,及相应的程序代码。
关键词:汉字编码, 函数, 语音系统
?
1.关于汉字映射序号函数 f
首先让我们来考查一下汉字的编码(我们这里只研究中国大陆的简体中文GB2312,下同)。
根据ANSI字符集[1],每一个汉字由两个字节构成,由一个十六进制数唯一表示,例如:‘黄’,其十六进制编码为:0xBBC6。我们可以看到在构成‘黄’字的这两个字节中,第一个字节表示的值为:0xBB,第二个字节为:0xC6。通过研究Windows系统中的字符映射表,我们可以得出以下命题:
命题一 在表示简体中文的这两个字节中,第一个字节的标识范围为:0xB0~0xF7,第二个字节的标识范围为:0xA1~0xFE。
根据命题一,我们得出:
命题二 用这两个字节在此标识范围之内所能表示的汉字个数为:
(0xF7-0xB0+1)×(0xFE-0xA1+1)=72×94=6768。
事实上字符映射表里的简体汉字个数也为6768个。
于是我们定义了一个函数f:
定义一: P = f(Q) = (Q1 – 0xB0) × 94 + (Q2 – 0xA1)
其中:Q为任一汉字的十六进制编码,显然这里Q由两个字节构成,Q1为构成Q的两个字节中的第一个字节,Q2为第二个字节,所以:
0xB0≤Q1≤0xF7, 0xA1≤Q2≤0xFE
P = {p | 0 ≤t≤ 6767 且 p为整数}
不难证明此函数是可逆的。得出命题三:
命题三 任意给定一汉字,根据函数f,总可以找到一个唯一的数p (pP),让p来代表这个汉字,反之,给定一数p(pP),也总有一个唯一的汉字与之对应。
于是我们有f(‘啊’) = f(0xB0A1) = 0,又如f(‘黄’) = f(0xBBC6) = 1071,如此等等。
?
2.关于汉字拼音对照表
通过考查《新华字典》[2],我们为字符映射表里的6768个简体汉字建立了一个汉语拼音对照表。对照表里在每一个拼音的后面加上一个数字,以示声调,第一声用‘1’表示,第二声用‘2’,第三声用‘3’, 第四声用‘4’,平声用‘5’。例如:‘啊’→ a1,‘黄’→huang2。由于汉字里同音字比较多,所以6768个汉字拼音里实际上不同声调者只有1317个。 为了准备基本的语音素材,我们特地从电视台请了一位播音员录制了这1317个不同的发音。其中每一个发音是一个单独的wav型文件,其文件名就是其对应的汉语拼音,例如‘huang2’这个音的文件名字就是‘huang2’。
3.关于语音库的建立
语音库分为两个部份,第一部份存贮6768个汉字中的每一个汉字语音数据在库中的位置索引,第二部份存贮的是已经录制好的1317个wav文件的数据。事实上在库中并没有存贮汉字本身,因为根据前面得到的命题三,字符映射表里的每一个汉字都有一个唯一的数字与其对应,故这个语音库的第一部份,也就是索引部份,可以看作一个有6768个元素的数组----SndIdx[6768] (实际我们后面编程时也是这样实现的),例如SndIdx[1071]的值是‘黄’这个字的语音数据在库中的位置偏移量。因为1317个语音数据有10M之多,故索引数组的元素值远超过32767,为此数组的每一个元素占有4个字节的空间。因此索引大小为:4 × 6768 ≈25K 。
调用语音库时利用了两个缓冲区 :DWORD SndIdx[6768] 与char? *m_szSndBuff,
m_szSndBuff = (char *)malloc( 语音库文件第二部份的大小 )。然后把语音库文件fsnd.dat的第一部份,也就是索引部份读入SndIdx;把第二部份,也就是语音数据部份读入m_szSndBuff。当需要语音输出的时候,例如要输出‘黄’的读音,程序根据定义一的函数f得出与该字对应的的编号为1071,于是得到该字的读音在缓冲区m_szSndBuff中的偏移量为SndIdx[1071],然后调用Windows的用于播放wav数据的API函数来输出该字的发音:
sndPlaySound( m_szSndBuff + SndIdx[1071] , SND_SYNC | SND_MEMORY )[3]。
?
4.关于系统的实现
首先我们来研究怎样生成这个语音系统。
语音系统的主体部份其实只是一个数据文件fsnd.dat,我们要做的只是怎样把这些索引与单
文档评论(0)