java語音轉(zhuǎn)文字代碼 java語言轉(zhuǎn)換

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

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

成都創(chuàng)新互聯(lián)長(zhǎng)期為上千客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為云溪企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè),云溪網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

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

二、實(shí)現(xiàn)語音引擎 語音引擎的實(shí)現(xiàn)只包括一個(gè)類,四個(gè)方法。它利用了J2SE 1.3包含的Java Sound API。在這里,我不準(zhǔn)備全面地介紹這個(gè)API,但你可以通過實(shí)例學(xué)習(xí)它的用法。Java Sound API并不是一個(gè)特別復(fù)雜的API,代碼中的注釋將告訴你必須了解的知識(shí)。 下面是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()方法將作為入口點(diǎn)運(yùn)行。main()方法獲取第一個(gè)命令行參數(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ù)雜,其實(shí)并非如此。實(shí)際上,它簡(jiǎn)單地遍歷所有單詞的語音元素(在輸入字符串中語音元素以“|”分隔),通過一個(gè)聲音輸出通道一個(gè)元素一個(gè)元素地播放出來。為了讓聲音更自然一些,我把每一個(gè)聲音樣本的結(jié)尾和下一個(gè)聲音樣本的開頭合并了起來: /* * 讀出指定的語音字符串 */ public void sayPhoneWord(String word) { // 為上一個(gè)聲音構(gòu)造的模擬byte數(shù)組 byte[] previousSound=null; // 把輸入字符串分割成單獨(dú)的音素 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) { // 如果可能的話,把前一個(gè)音素和當(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); } // 播放前一個(gè)音素 playSound(previousSound); // 把經(jīng)過截短的當(dāng)前音素作為前一個(gè)音素 byte[] newSound=new byte[thisSound.length-mergeCount]; for (int ii=0; ii newSound[ii]=thisSound[ii+mergeCount]; previousSound=newSound; } else previousSound=thisSound; } // 播放最后一個(gè)音素,清理聲音通道 playSound(previousSound); drain(); } 在sayPhoneWord()的后面,你可以看到它調(diào)用playSound()輸出單個(gè)聲音樣本(即一個(gè)音素),然后調(diào)用drain()清理聲音通道。下面是playSound()的代碼: /* * 該方法播放一個(gè)聲音樣本 */ 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(),這里還有一個(gè)方法我們沒有分析,即getSound()方法。 getSound()方法從一個(gè)au文件以字節(jié)數(shù)據(jù)的形式讀入預(yù)先錄制的聲音樣本。要了解讀取數(shù)據(jù)、轉(zhuǎn)換音頻格式、初始化聲音輸出行(SouceDataLine)以及構(gòu)造字節(jié)數(shù)據(jù)的詳細(xì)過程,請(qǐng)參考下面代碼中的注釋: /* * 該方法從文件讀取一個(gè)音素, * 并把它轉(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(); // 把一個(gè)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) { // 輸出線還沒有實(shí)例化 // 是否能夠找到合適的輸出線類型? 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ù),并計(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),一個(gè)大約150行代碼的語音合成器。

三、文本-語音轉(zhuǎn)換 以語音元素的格式指定待朗讀的單詞似乎過于復(fù)雜,如果要構(gòu)造一個(gè)能夠朗讀文本(比如Web頁(yè)面或Email)的應(yīng)用,我們希望能夠直接指定原始的文本。 深入分析這個(gè)問題之后,我在本文后面的ZIP文件中提供了一個(gè)試驗(yàn)性的文本-語音轉(zhuǎn)換類。運(yùn)行這個(gè)類,它將顯示出分析結(jié)果。文本-語音轉(zhuǎn)換類可以從命令行執(zhí)行,如下所示: java com.lotontech.speech.Converter "hello there" 輸出結(jié)果類如: hello - h|e|l|oo there - dth|aer 如果運(yùn)行下面這個(gè)命令: 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 這個(gè)轉(zhuǎn)換類是如何工作的呢?實(shí)際上,我的方法相當(dāng)簡(jiǎn)單,轉(zhuǎn)換過程就是以一定的次序應(yīng)用一組文本替換規(guī)則。例如對(duì)于單詞“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*” 對(duì)于“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”作為一個(gè)完整單詞優(yōu)先于其他規(guī)則,從而“unique”這個(gè)單詞讀作“y|ou...”而不是“u|n...”。

java可以實(shí)現(xiàn)語音識(shí)別嗎

這個(gè)是可以實(shí)現(xiàn)的。

注:test.pcm是語音文件,可以用audacity軟件打開,選擇 文件-導(dǎo)入-裸數(shù)據(jù)。 設(shè)置采樣率為8000Hz。點(diǎn)擊播放就能聽見聲音了。

這個(gè)時(shí)候程序跑起來還有問題,需要將apiKey 以及secretKey填寫上。這兩個(gè)值是你申請(qǐng)應(yīng)用對(duì)應(yīng)的分配好的。

cuid填本機(jī)mac地址就可以了,這個(gè)值我試過好像無所謂沒啥要求。

程序能跑起來,并且按照正常返回識(shí)別的語音結(jié)果。但是返回結(jié)果的編碼為GBK,所以漢字顯示為亂碼,需要對(duì)其進(jìn)行一次轉(zhuǎn)碼。轉(zhuǎn)碼的代碼是我自己加上去的

java如何實(shí)現(xiàn)中文語音轉(zhuǎn)換文字

沒有直接的java類庫(kù)調(diào)用,只能通過JNI技術(shù)調(diào)用操作系統(tǒng)提供的TTS支持才能實(shí)現(xiàn)。

Java有沒有語音處理的庫(kù)?錄音,語音轉(zhuǎn)文字之類的?

沒有的哦。不過想要將錄音或者語音轉(zhuǎn)換成文字的功能也是可以完成轉(zhuǎn)換的 。

當(dāng)需要完成轉(zhuǎn)換的時(shí)候。在錄音轉(zhuǎn)文字助手這個(gè)工具上是可以完成轉(zhuǎn)換的。

在應(yīng)用市場(chǎng)或者百度手機(jī)助手里面能夠幫助完成轉(zhuǎn)換的哦。

本文標(biāo)題:java語音轉(zhuǎn)文字代碼 java語言轉(zhuǎn)換
網(wǎng)頁(yè)路徑:http://bm7419.com/article38/dohgepp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器網(wǎng)站收錄、響應(yīng)式網(wǎng)站小程序開發(fā)、手機(jī)網(wǎng)站建設(shè)、微信小程序

廣告

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

綿陽服務(wù)器托管