热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LINUX运行谷歌TTS,中文TTS的简单实现(基于linux)之语音库的实现

语音库保存着常用汉字的发音(多音的汉字只记录其一种发音,这也是本系统的一个缺陷,需要以后完善),所以先要得到一汉字集,这个汉

语音库保存着常用汉字的发音(多音的汉字只记录其一种发音,这也是本系统的一个缺陷,需要以后完善),所以先要得到一汉字集,这个汉字集包含了大部分常用的汉字,然后在根据这个汉字集,来一个个的取得汉字的发音,并且按一定的规则保存到语音库中。所以实现语音库可以分为三步:

1.1:取得常用汉字的集合

1.2:根据汉字集,使用一些朗读软件生成该汉字集的语音文件

1.3:处理汉字集语音文件的格式,使它能符合我们的要求

1.1根据汉字编码规则获取汉字字符集的文本文件

1.1.1编码知识:所谓编码,是以固定的顺序排列字符,并以此作为记录、存贮、传递、交换的统一内部特征。一个汉字有ASC II码、区位码等与之对应。ASC II码中对应于码值161到254的字符用于表示汉字,每个汉字用两个ASC1I码值对应的字符表示。区位码用4位数字表示,前两位从01到94称区码,后两位从01到94称位码。一个汉字的前一半是ASC II码为“160+区码”的字符,后一半是ASCII码为“160+位码”的字符。例如:“刘”的区位码是3385,其意为区码33和位码85,它是由ASCII码为160+33=193和160+85=245的两个字符组成。该文所说的汉字字符集一般是指ISO 10646.1 即GB130o0.1。在Windows 95/98/2000中,微软提供了“汉字扩展内码规范(GBK)”以解决汉字的收字不足、简繁共存、简化代码体系间转换等汉字信息交换的瓶颈问题,利用GBK可以方便解决“镕”、“薯”等大量汉字的交换问题而不必自行造字了。GBK字库共分为5部分,其中GBK/1和GBK/5为符号部分,GBK/2为国标汉字部分,GBK/3和GBK/4为扩展汉字部分。其中,第16区至55区为一级汉字,以拼音排序,共计3755字,56—87区为二级汉字,按偏旁部首排序,共计3008字。

1.1.2程序代码:

用C++实现的获取GBK中一级汉字字符的代码段如下:

//getgbk.cpp一获取GBK汉字码文件

#include   //字符串I/O操作

#include    //文件I/O操作

unsigned char oneline[4];

ofstream ofs("gbhz.txt",ios::binary );

oneline[2]=163;

oneline[3]=172;

int qm;

int wm;

for( qm=176;qm<=247;qm++)  //区码0XB0—0XD7 87

for(wm=161;wm<=254;wm++) //位码0XA1—0XFE

if(!((qm==247)&&(wm=250)))

//剔除GBK中没有编码的字位

{

oneline[0]=qm; //汉字区码

oneline[1]=wm; //汉字位码

ofs.write((char *)&oneline,4); //写一行至gbhz txt

}//if end

1.2:根据取得的汉字集,使用一些报读软件生成该汉字集的语音文件,一般为WAV格式的。

这里取名为gbhz.wav1.3:处理汉字集读音文件的格式      1.3.1 理解WAV文件格式

WAVE文件作为多媒体中使用的声波文件格式之一.它是以RlFF格式为标准的 每个wAVE文件的头4个字节便是

“RIFF” WAVE文件由文件头和数据体两大部分组成。其中文件头又分为RIFE/WAV文件标识段和声音数据格式说明段两部分 。WAVE文件格式说明见下表,

内容

数据类型

字节数

“RIFF”标志

Char

4Byte

文件大小

Long int

4Byte

“wave”标志

Char

4Byte

“fmt”标志

Char

4Byte

PCMWAVFORMAT数据结构大小

Long int

4Byte

PCMWAVFORMAT数据结构

“data”标志

Char

4Byte

语音数据大小

Long int

4Byte

可以以时域-幅度的方式显示出原始声音的波形,这是最简单同时也是最直接的信息处理方式。在时域范国内,可以观察该信号波形是否连续,中间是否有祧变等。据发现,经语音引擎处理后,每个汉字所对应的语音数据长度不尽相同.这给以后截取每个汉字的语音数据造成了困难。因此.为了区分每个汉宇的语音数据.在生成汉字字符集时.在每个汉字后添加了一个逗号作为闻隔符 这样生成的语音文件的波形图(部分)如图1所示

图1:

%E5%9B%BE1.JPG

1.3.2生成新的汉字字符集的话音文件的算法

(1)打开gbhz.wav.从gbhz.wav中读人文件头CHAR HEAD[46]。46为文件头长度。

(2)从gbhz.wav 中读入第一个汉字的语音波形数据放入CHAR BUFFER[3200]。

3200为一个汉字的语音波形数据长度.选取决于形成语音的速率、音质等因素

(3)读后面的数据,如果是0x80则不做处理.继续往后读。

ox8O是逗号语音数据,既没有发音的数据。

(4)直到读到第一个不是逗号的语音数据,开始记录第二

个汉字的语音波形数据到CHAR BUFFER[3200]

(5)重复3.4步直到读完全部的语音波形数据。

合成新的汉字字符集的语音文件后的波形图(部分)如图2所示

图2:新的语音文件波形图

%E5%9B%BE2.JPG

1.3.3 处理代码如下:

#define  MAXLEN  32000

int HandingWav()

{

FILE * fpf,*fpt; //文件操作指针

if((fpf=fopen("gbhz.wav","rb+"))==NULL)   //gbhz.wav为处理前的语音文件

return -1;

if((fpt=fopen("ddd.wav","rb+"))==NULL)  //ddd.wav为合成的新的语音文件

return -1;

char head[46];     //wav文件的文件头长度

char data[100];    //用来加速文件处理的数组

char buffer[MAXLEN];

memset(buffer,0,MAXLEN);

fread(head,sizeof(head),1,fpf);    //head of wav

fwrite(head,sizeof(head),1,fpt);

while(!feof(fpf))

{

fread(buffer,MAXLEN,1,fpf);  //读一个字的发音

fwrite(buffer,MAXLEN,1,fpt);  //写一个字

memset(buffer,0,MAXLEN);

fread(data,1,1,fpf); //读一个字节

while(data[0]==char(0x80)) //判断是否为0x80

{

if(fread(data,100,1,fpf)==-1) //每次取100个字节,但只判断第一个字节,这样可以加速文件处理

{

fclose(fpf);

fclose(fpt);

return -1;

}  //end if

}  //end while  判断是否为0x80

}  // end while(!feof(fpf))

fclose(fpf);  //关闭文件

fclose(fpt);

return 0;

}

经过以上的操作后,就形成了我们所要的语音库了。

文章导读:



推荐阅读
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
author-avatar
你妈咪叫你吃饭呢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有