金色的骷髅 发表于 2015-1-18 11:45:10

JAVA网页设计用Java完成语音引擎

J2ME在手机游戏开发的作用也是无用质疑的。至于桌面程序,可能有人说java不行,界面不好看,但是请看看NetBeans和Eclipse吧,他们都是利用java开发的,而他们的界面是多么的华丽,所以界面决不是java的缺点。还有一个不得不提的优点就是大多java人员都挂在嘴边的java的跨平台性,目前这确实也是java优点之一。为使用程序加上语音才能有甚么优点呢?大略地讲,是为了兴趣,它合适一切注意兴趣的
使用,好比游戏。固然,从更严厉的角度来说,它还触及到使用的可用性成绩。注重,这
里我思索的不但是可视化界面固有的不敷,并且另有如许一些情况:一些时分,让双眼离
开以后的事情很不便利,乃至是分歧法的。好比,假定有一个带语音功效的扫瞄器,你就
能够在外出漫步或开车下班的同时,用听的体例扫瞄本人喜好的网站。

  从今朝来看,邮件浏览器也许是语音手艺更实践的使用,在JavaMailAPI的匡助下,
这统统已大概。邮件浏览器能够按期地反省收件箱,然后用语音“Youhavenewmail,
wouldyoulikemetoreadittoyou?”引发你的注重。依照相似的思绪,我们还能够
思索一个带语音功效的提示器,把它毗连到一个日历使用:它会实时地提示你“Dont
forgetyourmeetingwiththebossin10minutes!”。

  大概你已被这些主张吸引,大概有了本人更好的主张,如今让我们持续。起首我将
先容怎样启用本文供应的语音引擎,如许,假如你以为语音引擎的完成细节过于庞大,就
能够间接利用它而疏忽实在现细节。
  1、试用语音引擎

要利用这个语音引擎,你必需在CLASSPATH中到场本文供应的javatalk.jar文件,然后从
命令交运行(大概从Java程序挪用)com.lotontech.speech.Talker类。假如从命令交运
行,则命令为:

javacom.lotontech.speech.Talker"h|e|l|oo"

假如从Java程序挪用,则代码为:

com.lotontech.speech.Talkertalker=newcom.lotontech.speech.Talker();

talker.sayPhoneWord("h|e|l|oo");

如今,关于在命令行上(大概挪用sayPhoneWord()办法时)供应的“h|e|l|oo”字符串,你
也许有所不解。上面我就来注释一下。

语音引擎的事情道理是把微小的声响样本毗连起来,每个样本都是人的言语发音(英
语)的一个最小单元。这些声响样本称为音素(allophone)。每个要素对应一个、二
个大概三个字母。夙昔面“hello”的语音暗示能够看出,一些字母组合的发音不言而喻,
另有一些却不是很分明:

h--读音不言而喻

e--读音不言而喻

l--读音不言而喻,但注重两个“l”被简缩成了一个“l”。

OO--应当读作“hello”中的读音,不该读作“bot”、“too”中的读音。

上面是一个无效音素的清单:

a:如cat
b:如cab
c:如cat
d:如dot
e:如bet
f:如frog
g:如frog
h:如hog
i:如pig
j:如jig
k:如keg
l:如leg
m:如met
n:如begin
o:如not
p:如pot
r:如rot
s:如sat
t:如sat
u:如put
v:如have
w:如wet
y:如yet
z:如zoo
aa:如fake
ay:如hay
ee:如bee
ii:如high
oo:如go
bb:b的变更情势,重音分歧
dd:d的变更情势,重音分歧
ggg:g的变更情势,重音分歧
hh:h的变更情势,重音分歧
ll:l的变更情势,重音分歧
nn:n的变更情势,重音分歧
rr:r的变更情势,重音分歧
tt:t的变更情势,重音分歧
yy:y的变更情势,重音分歧
ar:如car
aer:如care
ch:如which
ck:如check
ear:如beer
er:如later
err:如later(长音)
ng:如feeding
or:如law
ou:如zoo
ouu:如zoo(长音)
ow:如cow
oy:如boy
sh:如shut
th:如thing
dth:如this
uh:u的变更情势
wh:如where
zh:如Asian

人措辞的时分,语音在全部句子以内升降变更。腔调变更使得语音更天然、更富有传染
力,使得问句和报告句可以互相区分。请思索上面两个句子:

Itisfake--f|aa|k

Isitfake?--f|AA|k

大概你已料想到,进步腔调的办法是利用年夜写字母。

以上就是利用该软件时你必要懂得的工具。假如你对厥后台完成细节感乐趣,请持续浏览。
  2、完成语音引擎

语音引擎的完成只包含一个类,四个办法。它使用了J2SE1.3包括的JavaSoundAPI。在
这里,我禁绝备周全地先容这个API,但你能够经由过程实例进修它的用法。JavaSoundAPI
并非一个出格庞大的API,代码中的正文将告知你必需懂得的常识。

上面是Talker类的基础界说:

packagecom.lotontech.speech;

importjavax.sound.sampled.*;

importjava.io.*;

importjava.util.*;

importjava.net.*;

publicclassTalker

{

privateSourceDataLineline=null;

}

假如从命令行实行Talker,上面的main()办法将作为出口点运转。main()办法猎取第一个
命令行参数,然后把它传送给sayPhoneWord()办法:

/*

*读出在命令行中指定的暗示读音的字符串

*/

publicstaticvoidmain(Stringargs[])

{

Talkerplayer=newTalker();

if(args.length>0)player.sayPhoneWord(args);

System.exit(0);

}
sayPhoneWord()办法既能够经由过程下面的main()办法挪用,也能够在Java程序中间接挪用。
从外表上看,sayPhoneWord()办法对照庞大,实在并不是云云。实践上,它复杂地遍历所
有单词的语音元素(在输出字符串中语音元素以“|”分开),经由过程一个声响输入通道一个
元素一个元素地播放出来。为了让声响更天然一些,我把每个声响样本的开头和下一个
声响样本的开首兼并了起来:

/*

*读出指定的语音字符串

*/

publicvoidsayPhoneWord(Stringword)

{

//为上一个声响机关的摹拟byte数组

byte[]previousSound=null;

//把输出字符串支解成独自的音素

StringTokenizerst=newStringTokenizer(word,"|",false);

while(st.hasMoreTokens())

{

//为音素机关响应的文件名字

StringthisPhoneFile=st.nextToken();

thisPhoneFile="/allophones/"+thisPhoneFile+".au";

//从声响文件读取数据

byte[]thisSound=getSound(thisPhoneFile);

if(previousSound!=null)

{

//假如大概的话,把前一个音素和以后音素兼并

intmergeCount=0;

if(previousSound.length>=500&&thisSound.length>=500)

mergeCount=500;

for(inti=0;i

{

previousSound

=(byte)((previousSound[previousSound.length

-mergeCount+i]+thisSound)/2);

}

//播放前一个音素

playSound(previousSound);

//把经由截短确当前音素作为前一个音素

byte[]newSound=newbyte;

for(intii=0;ii

newSound=thisSound;

previousSound=newSound;

}

else

previousSound=thisSound;

}

//播放最初一个音素,清算声响通道

playSound(previousSound);

drain();

}

在sayPhoneWord()的前面,你能够看到它挪用playSound()输入单个声响样本(即一个音
素),然后挪用drain()清算声响通道。上面是playSound()的代码:

/*

*该办法播放一个声响样本

*/

privatevoidplaySound(byte[]data)

{

if(data.length>0)line.write(data,0,data.length);

}

上面是drain()的代码:

/*

*该办法清算声响通道

*/

privatevoiddrain()

{

if(line!=null)line.drain();

try{Thread.sleep(100);}catch(Exceptione){}

}
如今回过火来看sayPhoneWord(),这里另有一个办法我们没有剖析,即getSound()办法。

getSound()办法从一个au文件以字节数据的情势读进事后录制的声响样本。要懂得读取数
据、转换音频格局、初始化声响输入行(SouceDataLine)和机关字节数据的具体过
程,请参考上面代码中的正文:

/*

*该办法从文件读取一个音素,

*并把它转换成byte数组

*/

privatebyte[]getSound(StringfileName)

{

try

{

URLurl=Talker.class.getResource(fileName);

AudioInputStreamstream=AudioSystem.getAudioInputStream(url);

AudioFormatformat=stream.getFormat();

//把一个ALAW/ULAW声响转换成PCM以便回放

if((format.getEncoding()==AudioFormat.Encoding.ULAW)||

(format.getEncoding()==AudioFormat.Encoding.ALAW))

{

AudioFormattmpFormat=newAudioFormat(

AudioFormat.Encoding.PCM_SIGNED,

format.getSampleRate(),format.getSampleSizeInBits()*2,

format.getChannels(),format.getFrameSize()*2,

format.getFrameRate(),true);

stream=AudioSystem.getAudioInputStream(tmpFormat,stream);

format=tmpFormat;

}

DataLine.Infoinfo=newDataLine.Info(

Clip.class,format,

((int)stream.getFrameLength()*format.getFrameSize()));

if(line==null)

{

//输入线还没有实例化

//是不是可以找到符合的输入线范例?

DataLine.InfooutInfo=newDataLine.Info(SourceDataLine.class,

format);

if(!AudioSystem.isLineSupported(outInfo))

{

System.out.println("不撑持婚配"+outInfo+"的输入线");

thrownewException("不撑持婚配"+outInfo+"的输入线");

}

//翻开输入线

line=(SourceDataLine)AudioSystem.getLine(outInfo);

line.open(format,50000);

line.start();

}

intframeSizeInBytes=format.getFrameSize();

intbufferLengthInFrames=line.getBufferSize()/8;

intbufferLengthInBytes=bufferLengthInFrames*frameSizeInBytes;

byte[]data=newbyte;

//读取字节数据,并计数

intnumBytesRead=0;

if((numBytesRead=stream.read(data))!=-1)

{

intnumBytesRmaining=numBytesRead;

}

//把字节数据切割成符合的巨细

byte[]newData=newbyte;

for(inti=0;i

newData=data;

returnnewData;

}

catch(Exceptione)

{

returnnewbyte;

}

}

这就是全体的代码,包含正文在内,一个约莫150行代码的语音分解器。
  3、文本-语音转换

以语音元素的格局指定待朗诵的单词仿佛过于庞大,假如要机关一个可以朗诵文本(好比
Web页面或Email)的使用,我们但愿可以间接指定原始的文本。

深切剖析这个成绩以后,我在本文前面的ZIP文件中供应了一个实验性的文本-语音转换
类。运转这个类,它将显现出剖析了局。文本-语音转换类能够从命令行实行,以下所示:

javacom.lotontech.speech.Converter"hellothere"

输入了局类如:

hello->h|e|l|oo

there->dth|aer

假如运转上面这个命令:

javacom.lotontech.speech.Converter"IliketoreadJavaWorld"

则输入了局为:

i->ii

like->l|ii|k

to->t|ouu

read->r|ee|a|d

java->j|a|v|a

world->w|err|l|d

这个转换类是怎样事情的呢?实践上,我的办法相称复杂,转换历程就是以必定的序次应
用一组文本交换划定规矩。比方关于单词“ant”、“want”、“wanted”、“unwanted”和
“unique”,则我们想要使用的交换划定规矩大概顺次为:

用“|y|ou|n|ee|k|”交换“*unique*”

用“|w|o|n|t|”交换“*want*”

用“|a|”交换“*a*”

用“|e|”交换“*e*”

用“|d|”交换“*d*”

用“|n|”交换“*n*”

用“|u|”交换“*u*”

用“|t|”交换“*t*”

关于“unwanted”,输入序列为:

unwanted

un[|w|o|n|t|]ed(划定规矩2)

[|u|][|n|][|w|o|n|t|][|e|][|d|](划定规矩4、5、6、7)

u|n|w|o|n|t|e|d(删除过剩的符以后)

你将看到包括字母“wont”的单词和包括字母“ant”的单词以分歧的体例发音,还将看到在
惯例划定规矩的感化下,“unique”作为一个完全单词优先于其他划定规矩,从而“unique”这个单词
读作“y|ou...”而不是“u|n...”。

  停止语:本文供应了一个能够随时运转的、便利的语音引擎,你能够在本人的Java
1.3使用中利用它。假如细心剖析一下代码,它还为你供应了一个用JavaSoundAPI播放音
频片段的有用教程。要让它变得真正有效,你应当思索一下文本-语音转换手艺,由于对
于我后面提到的文本浏览使用来讲,这是真实的支持基本。要改良本文计划的效果,你必
须机关出一个复杂的交换划定规矩库,经心调剂使用划定规矩的优先序次。但愿你比我更有毅力!
到时我们不用学struts,不用学spring,不用学Hibernate,只要能把jsf学会了,完全可以替代所有的框架,包括AJAX,都知道AJAX并不是新技术,虽说我没深入学习jsf但我认为jsf应该已经能通过其它技术替代AJAX,实现无缝刷新。

精灵巫婆 发表于 2015-1-21 13:55:21

另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。

蒙在股里 发表于 2015-1-30 19:43:41

Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站

谁可相欹 发表于 2015-2-8 06:04:54

你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?

若天明 发表于 2015-2-11 16:15:44

如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。

变相怪杰 发表于 2015-3-2 15:48:37

http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。

灵魂腐蚀 发表于 2015-3-10 08:11:07

吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧

兰色精灵 发表于 2015-3-11 11:25:01

吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧

莫相离 发表于 2015-3-18 07:56:01

Java 编程语言的风格十分接近C、C++语言。

不帅 发表于 2015-3-18 22:13:35

Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。

只想知道 发表于 2015-3-20 10:51:26

是一种突破用户端机器环境和CPU

若相依 发表于 2015-4-1 00:11:45

有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)

柔情似水 发表于 2015-4-5 02:21:33

你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。

深爱那片海 发表于 2015-4-10 08:44:12

你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。

海妖 发表于 2015-4-10 08:46:28

你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?

山那边是海 发表于 2015-4-13 22:56:51

任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言

仓酷云 发表于 2015-4-15 07:15:58

如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。

愤怒的大鸟 发表于 2015-4-21 03:21:09

不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。

乐观 发表于 2015-5-9 11:50:05

是一种突破用户端机器环境和CPU
页: [1]
查看完整版本: JAVA网页设计用Java完成语音引擎