語音朗讀java代碼 java語音播報開發(fā)

java關(guān)于播放聲音的代碼的解釋

playCycle(String s)這個是單曲重復(fù)播放;play(String s)這個是單曲播放。

創(chuàng)新互聯(lián)建站于2013年開始,先為五大連池等服務(wù)建站,五大連池等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為五大連池企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

/******* part one start *******/

//獲取媒體文件流

AudioInputStream ais = AudioSystem.getAudioInputStream(new File(fileurl));

//獲取文件格式

AudioFormat aif = ais.getFormat();

//這個類不知道是什么,沒用過,在這里應(yīng)該是對媒體流處理的一個類

SourceDataLine sdl = null;

//這個貌似通過媒體格式,獲取媒體文件的信息

DataLine.Info info = new DataLine.Info(SourceDataLine.class,aif);

//通過媒體文件的信息初始化處理媒體文件的類

sdl = (SourceDataLine)AudioSystem.getLine(info);

//媒體工具類 打開媒體流

sdl.open(aif);

//媒體工具(播放器)開啟

sdl.start();

/******* part one end *******/

/******* part two start ********/

int nByte = 0;

byte[] buffer = new byte[128];

//媒體工具類(播放器類)對媒體流進行寫入處理,此時應(yīng)該會有音樂響起吧

while(nByte != -1){

nByte = ais.read(buffer,0,128);

if(nByte = 0){

int oByte = sdl.write(buffer, 0, nByte);

//System.out.println(oByte);

}

}

//媒體流結(jié)束,并關(guān)閉這個媒體工具類

sdl.stop();

/******* part two end********/

在java程序中加入語音功能,例如給段字符串“A101”,就能發(fā)出聲音,請大家?guī)蛶兔?,謝謝

為應(yīng)用程序加上語音能力有什么好處呢?粗略地講,是為了趣味,它適合所有注重趣味的應(yīng)用,比如游戲。當(dāng)然,從更嚴(yán)肅的角度來講,它還涉及到應(yīng)用的可用性問題。注意,這里我考慮的不僅是可視化界面固有的不足,而且還有這樣一些情形:一些時候,讓雙眼離開當(dāng)前的工作很不方便,甚至是不合法的。比如,假設(shè)有一個帶語音功能的瀏覽器,你就可以在外出散步或開車上班的同時,用聽的方式瀏覽自己喜愛的網(wǎng)站。從目前來看,郵件閱讀器或許是語音技術(shù)更實際的應(yīng)用,在JavaMail API的幫助下,這一切已經(jīng)可能。郵件閱讀器可以定期地檢查收件箱,然后用語音“You have new mail, would you like me to read it to you?”引起你的注意。按照類似的思路,我們還可以考慮一個帶語音功能的提醒器,把它連接到一個日歷應(yīng)用:它會及時地提醒你“Don't forget your meeting with the boss in 10 minutes!”。 也許你已經(jīng)被這些主意吸引,或者有了自己更好的主意,現(xiàn)在讓我們繼續(xù)。首先我將介紹如何啟用本文提供的語音引擎,這樣,如果你認(rèn)為語音引擎的實現(xiàn)細(xì)節(jié)過于復(fù)雜,就可以直接使用它而忽略其實現(xiàn)細(xì)節(jié)。

一、試用語音引擎 要使用這個語音引擎,你必須在CLASSPATH中加入本文提供的javatalk.jar文件,然后從命令行運行(或者從Java程序調(diào)用)com.lotontech.speech.Talker類。如果從命令行運行,則命令為: java com.lotontech.speech.Talker "h|e|l|oo" 如果從Java程序調(diào)用,則代碼為: com.lotontech.speech.Talker talker=new com.lotontech.speech.Talker(); talker.sayPhoneWord("h|e|l|oo"); 現(xiàn)在,對于在命令行上(或者調(diào)用sayPhoneWord()方法時)提供的“h|e|l|oo”字符串,你或許有所不解。下面我就來解釋一下。 語音引擎的工作原理是把細(xì)小的聲音樣本連接起來,每一個樣本都是人的語言發(fā)音(英語)的一個最小單位。這些聲音樣本稱為音素(allophone)。每一個因素對應(yīng)一個、二個或者三個字母。從前面“hello”的語音表示可以看出,一些字母組合的發(fā)音顯而易見,還有一些卻不是很明顯: h -- 讀音顯而易見 e -- 讀音顯而易見 l -- 讀音顯而易見,但注意兩個“l(fā)”被簡縮成了一個“l(fā)”。 OO -- 應(yīng)該讀作“hello”中的讀音,不應(yīng)讀作“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 人說話的時候,語音在整個句子之內(nèi)起落變化。語調(diào)變化使得語音更自然、更富有感染力,使得問句和陳述句能夠相互區(qū)別。請考慮下面兩個句子: It is fake -- f|aa|k Is it fake? -- f|AA|k 也許你已經(jīng)猜想到,提高語調(diào)的方法是使用大寫字母。 以上就是使用該軟件時你需要了解的東西。如果你對其后臺實現(xiàn)細(xì)節(jié)感興趣,請繼續(xù)閱讀。

二、實現(xiàn)語音引擎 語音引擎的實現(xiàn)只包括一個類,四個方法。它利用了J2SE 1.3包含的Java Sound API。在這里,我不準(zhǔn)備全面地介紹這個API,但你可以通過實例學(xué)習(xí)它的用法。Java Sound API并不是一個特別復(fù)雜的API,代碼中的注釋將告訴你必須了解的知識。 下面是Talker類的基本定義: package com.lotontech.speech; import javax.sound.sampled.*; import java.io.*; import java.util.*; import java.net.*; public class Talker { private SourceDataLine line=null; } 如果從命令行執(zhí)行Talker,下面的main()方法將作為入口點運行。main()方法獲取第一個命令行參數(shù),然后把它傳遞給sayPhoneWord()方法: /* * 讀出在命令行中指定的表示讀音的字符串 */ public static void main(String args[]) { Talker player=new Talker(); if (args.length0) player.sayPhoneWord(args[0]); System.exit(0); }

sayPhoneWord()方法既可以通過上面的main()方法調(diào)用,也可以在Java程序中直接調(diào)用。從表面上看,sayPhoneWord()方法比較復(fù)雜,其實并非如此。實際上,它簡單地遍歷所有單詞的語音元素(在輸入字符串中語音元素以“|”分隔),通過一個聲音輸出通道一個元素一個元素地播放出來。為了讓聲音更自然一些,我把每一個聲音樣本的結(jié)尾和下一個聲音樣本的開頭合并了起來: /* * 讀出指定的語音字符串 */ public void sayPhoneWord(String word) { // 為上一個聲音構(gòu)造的模擬byte數(shù)組 byte[] previousSound=null; // 把輸入字符串分割成單獨的音素 StringTokenizer st=new StringTokenizer(word,"|",false); while (st.hasMoreTokens()) { // 為音素構(gòu)造相應(yīng)的文件名字 String thisPhoneFile=st.nextToken(); thisPhoneFile="/allophones/"+thisPhoneFile+".au"; // 從聲音文件讀取數(shù)據(jù) byte[] thisSound=getSound(thisPhoneFile); if (previousSound!=null) { // 如果可能的話,把前一個音素和當(dāng)前音素合并 int mergeCount=0; if (previousSound.length=500 thisSound.length=500) mergeCount=500; for (int i=0; i { previousSound[previousSound.length-mergeCount+i] =(byte)((previousSound[previousSound.length -mergeCount+i]+thisSound[i])/2); } // 播放前一個音素 playSound(previousSound); // 把經(jīng)過截短的當(dāng)前音素作為前一個音素 byte[] newSound=new byte[thisSound.length-mergeCount]; for (int ii=0; ii newSound[ii]=thisSound[ii+mergeCount]; previousSound=newSound; } else previousSound=thisSound; } // 播放最后一個音素,清理聲音通道 playSound(previousSound); drain(); } 在sayPhoneWord()的后面,你可以看到它調(diào)用playSound()輸出單個聲音樣本(即一個音素),然后調(diào)用drain()清理聲音通道。下面是playSound()的代碼: /* * 該方法播放一個聲音樣本 */ private void playSound(byte[] data) { if (data.length0) line.write(data, 0, data.length); } 下面是drain()的代碼: /* * 該方法清理聲音通道 */ private void drain() { if (line!=null) line.drain(); try {Thread.sleep(100);} catch (Exception e) {} }

現(xiàn)在回過頭來看sayPhoneWord(),這里還有一個方法我們沒有分析,即getSound()方法。 getSound()方法從一個au文件以字節(jié)數(shù)據(jù)的形式讀入預(yù)先錄制的聲音樣本。要了解讀取數(shù)據(jù)、轉(zhuǎn)換音頻格式、初始化聲音輸出行(SouceDataLine)以及構(gòu)造字節(jié)數(shù)據(jù)的詳細(xì)過程,請參考下面代碼中的注釋: /* * 該方法從文件讀取一個音素, * 并把它轉(zhuǎn)換成byte數(shù)組 */ private byte[] getSound(String fileName) { try { URL url=Talker.class.getResource(fileName); AudioInputStream stream = AudioSystem.getAudioInputStream(url); AudioFormat format = stream.getFormat(); // 把一個ALAW/ULAW聲音轉(zhuǎn)換成PCM以便回放 if ((format.getEncoding() == AudioFormat.Encoding.ULAW) || (format.getEncoding() == AudioFormat.Encoding.ALAW)) { AudioFormat tmpFormat = new AudioFormat( 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.Info info = new DataLine.Info( Clip.class, format, ((int) stream.getFrameLength() * format.getFrameSize())); if (line==null) { // 輸出線還沒有實例化 // 是否能夠找到合適的輸出線類型? DataLine.Info outInfo = new DataLine.Info(SourceDataLine.class, format); if (!AudioSystem.isLineSupported(outInfo)) { System.out.println("不支持匹配" + outInfo + "的輸出線"); throw new Exception("不支持匹配" + outInfo + "的輸出線"); } // 打開輸出線 line = (SourceDataLine) AudioSystem.getLine(outInfo); line.open(format, 50000); line.start(); } int frameSizeInBytes = format.getFrameSize(); int bufferLengthInFrames = line.getBufferSize() / 8; int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes; byte[] data=new byte[bufferLengthInBytes]; // 讀取字節(jié)數(shù)據(jù),并計數(shù) int numBytesRead = 0; if ((numBytesRead = stream.read(data)) != -1) { int numBytesRemaining = numBytesRead; } // 把字節(jié)數(shù)據(jù)切割成合適的大小 byte[] newData=new byte[numBytesRead]; for (int i=0; i newData[i]=data[i]; return newData; } catch (Exception e) { return new byte[0]; } } 這就是全部的代碼,包括注釋在內(nèi),一個大約150行代碼的語音合成器。

三、文本-語音轉(zhuǎn)換 以語音元素的格式指定待朗讀的單詞似乎過于復(fù)雜,如果要構(gòu)造一個能夠朗讀文本(比如Web頁面或Email)的應(yīng)用,我們希望能夠直接指定原始的文本。 深入分析這個問題之后,我在本文后面的ZIP文件中提供了一個試驗性的文本-語音轉(zhuǎn)換類。運行這個類,它將顯示出分析結(jié)果。文本-語音轉(zhuǎn)換類可以從命令行執(zhí)行,如下所示: java com.lotontech.speech.Converter "hello there" 輸出結(jié)果類如: hello - h|e|l|oo there - dth|aer 如果運行下面這個命令: java com.lotontech.speech.Converter "I like to read JavaWorld" 則輸出結(jié)果為: i - ii like - l|ii|k to - t|ouu read - r|ee|a|d java - j|a|v|a world - w|err|l|d 這個轉(zhuǎn)換類是如何工作的呢?實際上,我的方法相當(dāng)簡單,轉(zhuǎn)換過程就是以一定的次序應(yīng)用一組文本替換規(guī)則。例如對于單詞“ant”、“want”、“wanted”、“unwanted”和“unique”,則我們想要應(yīng)用的替換規(guī)則可能依次為: 用“|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 (規(guī)則2) [|u|][|n|][|w|o|n|t|][|e|][|d|] (規(guī)則4、5、6、7) u|n|w|o|n|t|e|d (刪除多余的符之后) 你將看到包含字母“wont”的單詞和包含字母“ant”的單詞以不同的方式發(fā)音,還將看到在特例規(guī)則的作用下,“unique”作為一個完整單詞優(yōu)先于其他規(guī)則,從而“unique”這個單詞讀作“y|ou...”而不是“u|n...”。

java使用freeTTS,怎么能讓機器輸出中文語言

FreeTTS可以輸出中文語言過程:

①導(dǎo)入Java 語音API包

②為語音合成器聲明實例變量

③語音合成器的初始化

初始化是FreeTTS應(yīng)用中關(guān)鍵的部分。首先需要建立一個SynthesizerModeDesc 對象,該對象用于指明語音合成器的屬性,包括語音引擎的的名稱、語音引擎的操作模式、支持的語言、語音引擎的運行狀態(tài)以及其發(fā)音能力等。

④創(chuàng)建語音合成器

創(chuàng)建語言合成器時需要用到Cen t ral 類, 其作用是提供用來訪問所有語音輸入和輸出的能力, 同時也可以定為語言引擎, 根據(jù)描述符所定義的屬性集合選擇匹配的引擎, 從而創(chuàng)建語音識別器和語音合成器。語音合成器的創(chuàng)建需使用Central類的createSynthesizer方法,該方法接受一個SynthesizerModeDesc描述符并返回同描述符中所指定屬性相匹配的一個Synthesizer對象,用以實現(xiàn)語音合成。

⑤準(zhǔn)備用于朗讀的Synthesizer 對象

該部分通過Synthesizer對象的allocate和resume方法分配語音引擎所需要的資源并取得可用于朗讀的語音合成器。實現(xiàn)較為簡單:speechSynthesizer1allocate();speechSynthesizer1resume();

⑥設(shè)置Syn thesizer 對象的屬性

利用getSynthesizerProperties 方法可以獲得Synthesizer對象的屬性,其返回值是與語音合成器相關(guān)聯(lián)的SynthesizerProperties對象,該對象包含語音合成器的多種屬性, 每種屬性可以通過setProperties方法設(shè)置。例如: setSpeakingRate方法可設(shè)置speakingRate屬性,實現(xiàn)每分鐘朗讀單詞速率的控制。

⑦事件處理程序設(shè)計

speak ingRate 屬性, 實現(xiàn)每分鐘朗讀單詞速率的控制。完成應(yīng)用程序界面中JButton“讀出號碼”的事件程序設(shè)計, 首先通過JComboBox(選擇人名的下拉列表)取得人名(namesArray)的一個索引,該索引與電話號碼索引(numbersArray)保持對應(yīng),然后調(diào)用Synthesizer對象speakingPlainText方法朗讀整理后的電話號碼字符串。

標(biāo)題名稱:語音朗讀java代碼 java語音播報開發(fā)
文章鏈接:http://muchs.cn/article22/doeoijc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號網(wǎng)站內(nèi)鏈、網(wǎng)站維護移動網(wǎng)站建設(shè)、域名注冊、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化