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

}

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

文章导读:



推荐阅读
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 1、字符型常量字符型常量指单个字符,是用一对单引号及其所括起来的字符表示。例如:‘A’、‘a’、‘0’、’$‘等都是字符型常量。C语言的字符使用的就是 ... [详细]
  • 本文介绍了Linux系统中的文件IO操作,包括文件描述符、基本文件操作函数以及目录操作。详细解释了各个函数的参数和返回值,并提供了代码示例。 ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • 本文详细介绍了C语言中的基本数据类型,包括整型、浮点型、字符型及其各自的子类型,并探讨了这些类型在不同编译环境下的表现。 ... [详细]
  • MapReduce原理是怎么剖析的
    这期内容当中小编将会给大家带来有关MapReduce原理是怎么剖析的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1 ... [详细]
  • 本文探讨了C++中如何正确使用+运算符来处理字符串和数字的拼接问题,分析了为何某些操作有效而另一些则会引发编译错误。 ... [详细]
  • 本题旨在通过给定的评级信息,利用拓扑排序和并查集算法来确定全球 Tetris 高手排行榜。题目要求判断是否可以根据提供的信息生成一个明确的排名表,或者是否存在冲突或信息不足的情况。 ... [详细]
  • 本文介绍了一种根据目标检测结果,从原始XML文件中提取并分析特定类别的方法。通过解析XML文件,筛选出特定类别的图像和标注信息,并保存到新的文件夹中,以便进一步分析和处理。 ... [详细]
  • MATLAB 数据读取与绘图实践
    本文详细介绍了如何使用 MATLAB 进行数据文件的选择、读取及处理,并最终绘制图形。重点在于数据的提取和转换过程。 ... [详细]
  • 大数据基础:JavaSE_day06 ... [详细]
  • 第十一章 Python基本数据类型及内置方法
    一、概述数据类型是用来记录事物状态的,而事物的状态是不断变化的(如:一个人年龄的增长(操作int类型),单个人名的修改(操作str类型),学生列表中增加学生(操作list类型)等) ... [详细]
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社区 版权所有