热门标签 | 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;

}

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

文章导读:



推荐阅读
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 1、字符型常量字符型常量指单个字符,是用一对单引号及其所括起来的字符表示。例如:‘A’、‘a’、‘0’、’$‘等都是字符型常量。C语言的字符使用的就是 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • 本文详细介绍了C语言中的基本数据类型,包括整型、浮点型、字符型及其各自的子类型,并探讨了这些类型在不同编译环境下的表现。 ... [详细]
  • MATLAB 数据读取与绘图实践
    本文详细介绍了如何使用 MATLAB 进行数据文件的选择、读取及处理,并最终绘制图形。重点在于数据的提取和转换过程。 ... [详细]
  • 优化联通光猫DNS服务器设置
    本文详细介绍了如何为联通光猫配置DNS服务器地址,以提高网络解析效率和访问体验。通过智能线路解析功能,域名解析可以根据访问者的IP来源和类型进行差异化处理,从而实现更优的网络性能。 ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 本文介绍了一种根据目标检测结果,从原始XML文件中提取并分析特定类别的方法。通过解析XML文件,筛选出特定类别的图像和标注信息,并保存到新的文件夹中,以便进一步分析和处理。 ... [详细]
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社区 版权所有