認(rèn)識(shí) TTS
1.TTS定義
TextToSpeech簡(jiǎn)稱 TTS,稱為語(yǔ)音合成,是Android 從1.6版本開(kāi)始支持的新功能,能將所指定的文本轉(zhuǎn)成不同語(yǔ)言音頻輸出,文字轉(zhuǎn)語(yǔ)音(text-to-speech,TTS)系統(tǒng)是將一般語(yǔ)言的文字轉(zhuǎn)換為語(yǔ)音。
TTS功能需要有TTS?Engine的支持,下面我們就來(lái)了解下android提供的TTS?Engine。
Android使用了叫Pico的支持多種語(yǔ)言的語(yǔ)音合成引擎,Pico在后臺(tái)負(fù)責(zé)把分析輸入的文本,把分本分成他能識(shí)別的各個(gè)片段,再把合成的各個(gè)語(yǔ)音片段以聽(tīng)起來(lái)比較自然的方式連接在一起,這個(gè)過(guò)程Android系統(tǒng)幫我們做,我們只把他當(dāng)做一個(gè)神奇的過(guò)程就可以了。
TTS?engine依托于當(dāng)前?Android?Platform?所支持的幾種主要的語(yǔ)言:?English?、?French?、?German?、?Italian?和Spanish?五大語(yǔ)言?(暫時(shí)也是沒(méi)有對(duì)中文提供支持)。?TTS可以將文本隨意的轉(zhuǎn)換成以上任意五種語(yǔ)言的語(yǔ)音輸出。與此同時(shí),對(duì)于個(gè)別的語(yǔ)言版本將取決于不同的時(shí)區(qū),例如:對(duì)于?English?,在?TTS?中可以分別輸出美式和英式兩種不同的版本?。
2.語(yǔ)音合成歷史
早在17世紀(jì)就有法國(guó)人研發(fā)機(jī)械式的說(shuō)話裝置。直到19世紀(jì),貝爾實(shí)驗(yàn)室對(duì)于電子語(yǔ)音合成技術(shù)的研究,才開(kāi)啟近代語(yǔ)音合成技術(shù)的發(fā)展。貝爾實(shí)驗(yàn)室在1939年制作出第一個(gè)電子語(yǔ)音合成器VODER,是一種利用共振峰原理所制作的合成器。
1960年,瑞典語(yǔ)言學(xué)家G. Fant則提出利用線性預(yù)測(cè)編碼技術(shù)(LPC)來(lái)作為語(yǔ)音合成分析技術(shù),并推動(dòng)了日后的發(fā)展。后來(lái)1980年代Moulines E和Charpentier F提出新的語(yǔ)音合成算法PSOLA,此技術(shù)可以合成比較自然的語(yǔ)音。
3.TTS 實(shí)例 (?了解 Android 的 TTS 使用方法 )
要求:在文本框中輸入英文句子,點(diǎn)擊按鈕然后朗讀出來(lái)。
框架:
1.先用?startActivityForResult()?檢查 TTS 數(shù)據(jù)是否已經(jīng)安裝并且可用
2.用?onInit()實(shí)現(xiàn)TTS初始化接口
3.實(shí)現(xiàn)按鈕的?OnClickListener() 接口, 接口中調(diào)用?speak(inputText.getText().toString(), TextToSpeech.QUEUE_ADD, null)?朗讀輸入框里的內(nèi)容.
Java代碼:
package?com.example.androidttsdemo1; import?java.util.Locale; import?android.app.Activity; import?android.content.Intent; import?android.os.Bundle; import?android.speech.tts.TextToSpeech; import?android.speech.tts.TextToSpeech.OnInitListener; import?android.util.Log; import?android.view.View; import?android.view.View.OnClickListener; import?android.widget.Button; import?android.widget.EditText; public?class?MainActivity?extends?Activity?implements?OnInitListener?{ ????/** ?????*?Called?when?the?activity?is?first?created. ?????*/ ????private?EditText?inputText?=?null; ????private?Button?speakBtn?=?null; ????private?static?final?int?REQ_TTS_STATUS_CHECK?=?0; ????private?static?final?String?TAG?=?"TTS?Demo"; ????private?TextToSpeech?mTts; ????@Override ????public?void?onCreate(Bundle?savedInstanceState)?{ ????????super.onCreate(savedInstanceState); ????????setContentView(R.layout.fragment_main); ????????//檢查T(mén)TS數(shù)據(jù)是否已經(jīng)安裝并且可用 ????????Intent?checkIntent?=?new?Intent(); ????????checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); ????????startActivityForResult(checkIntent,?REQ_TTS_STATUS_CHECK); ????????inputText?=?(EditText)?findViewById(R.id.inputText); ????????speakBtn?=?(Button)?findViewById(R.id.speakBtn); ????????inputText.setText("This?is?an?example?of?speech?synthesis."); ????????speakBtn.setOnClickListener(new?OnClickListener()?{ ????????????public?void?onClick(View?v)?{ ????????????????//?TODO?Auto-generated?method?stub ????????????????mTts.speak(inputText.getText().toString(),?TextToSpeech.QUEUE_ADD,?null); ????????????????//朗讀輸入框里的內(nèi)容 ????????????} ????????}); ????} ????//實(shí)現(xiàn)TTS初始化接口 ????@Override ????public?void?onInit(int?status)?{ ????????//?TODO?Auto-generated?method?stub ????????//TTS?Engine初始化完成 ????????if?(status?==?TextToSpeech.SUCCESS)?{ ????????????int?result?=?mTts.setLanguage(Locale.US); ????????????//設(shè)置發(fā)音語(yǔ)言 ????????????if?(result?==?TextToSpeech.LANG_MISSING_DATA?||?result?==?TextToSpeech.LANG_NOT_SUPPORTED) ????????????//判斷語(yǔ)言是否可用 ????????????{ ????????????????Log.v(TAG,?"Language?is?not?available"); ????????????????speakBtn.setEnabled(false); ????????????}?else?{ ????????????????mTts.speak("This?is?an?example?of?speech?synthesis.",?TextToSpeech.QUEUE_ADD,?null); ????????????????speakBtn.setEnabled(true); ????????????} ????????} ????} ????protected?void?onActivityResult(int?requestCode,?int?resultCode,?Intent?data)?{ ????????if?(requestCode?==?REQ_TTS_STATUS_CHECK)?{ ????????????switch?(resultCode)?{ ????????????????case?TextToSpeech.Engine.CHECK_VOICE_DATA_PASS: ????????????????????//這個(gè)返回結(jié)果表明TTS?Engine可以用 ????????????????{ ????????????????????mTts?=?new?TextToSpeech(this,?this); ????????????????????Log.v(TAG,?"TTS?Engine?is?installed!"); ????????????????} ????????????????break; ????????????????case?TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA: ????????????????????//需要的語(yǔ)音數(shù)據(jù)已損壞 ????????????????case?TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA: ????????????????????//缺少需要語(yǔ)言的語(yǔ)音數(shù)據(jù) ????????????????case?TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME: ????????????????????//缺少需要語(yǔ)言的發(fā)音數(shù)據(jù) ????????????????{ ????????????????????//這三種情況都表明數(shù)據(jù)有錯(cuò),重新下載安裝需要的數(shù)據(jù) ????????????????????Log.v(TAG,?"Need?language?stuff:"?+?resultCode); ????????????????????Intent?dataIntent?=?new?Intent(); ????????????????????dataIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); ????????????????????startActivity(dataIntent); ????????????????} ????????????????break; ????????????????case?TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL: ????????????????????//檢查失敗 ????????????????default: ????????????????????Log.v(TAG,?"Got?a?failure.?TTS?apparently?not?available"); ????????????????????break; ????????????} ????????}?else?{ ????????????//其他Intent返回的結(jié)果 ????????} ????} ????@Override ????protected?void?onPause()?{ ????????//?TODO?Auto-generated?method?stub ????????super.onPause(); ????????if?(mTts?!=?null) ????????//activity暫停時(shí)也停止TTS ????????{ ????????????mTts.stop(); ????????} ????} ????@Override ????protected?void?onDestroy()?{ ????????//?TODO?Auto-generated?method?stub ????????super.onDestroy(); ????????//釋放TTS的資源 ????????mTts.shutdown(); ????} }
下面簡(jiǎn)單介紹下上面代碼中和TTS相關(guān)的一些API使用。
1. 首先是實(shí)現(xiàn)OnInitListener這個(gè)接口,這個(gè)接口中只有一個(gè)抽象函數(shù)void onInit(int status),在TextToSpeech引擎初始化完成后調(diào)用,在這個(gè)函數(shù)里就可以根據(jù)狀態(tài)status(為T(mén)extToSpeech.SUCCESS或者TextToSpeech.Error)判斷TTS初始化成功與否進(jìn)行相應(yīng)的操作。
2. 接著在使用TTS時(shí),會(huì)先啟動(dòng)一個(gè)Activity檢查T(mén)TS引擎需要的TTS數(shù)據(jù)是否已經(jīng)安裝并且可用,checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);這個(gè)Activity會(huì)返回如下結(jié)果之一:CHECK_VOICE_DATA_PASS, CHECK_VOICE_DATA_FAIL, CHECK_VOICE_DATA_BAD_DATA,
CHECK_VOICE_DATA_MISSING_DATA, 或者CHECK_VOICE_DATA_MISSING_VOLUME.?
只有第一個(gè)結(jié)果CHECK_VOICE_DATA_PASS表明TTS數(shù)據(jù)可用,其他都是數(shù)據(jù)不可用的結(jié)果,可以啟動(dòng)一個(gè)Activity去安裝需要的TTS數(shù)據(jù),dataIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
3. 當(dāng)數(shù)據(jù)可用時(shí),就可以創(chuàng)建一個(gè)TextToSpeech實(shí)例,
public TextToSpeech (Context context, TextToSpeech.OnInitListener?listener)
這里需要兩個(gè)參數(shù),一個(gè)是TTS實(shí)例運(yùn)行的Context;
另一個(gè)是初始化接口的實(shí)現(xiàn),在實(shí)例的創(chuàng)建過(guò)程中,如果TTS引擎沒(méi)有運(yùn)行的話,則會(huì)初始化TTS引擎,并且在初始化完成后調(diào)用其第二個(gè)參數(shù)listener。
4. 有了TextToSpeech實(shí)例,接下來(lái)就可以對(duì)文本進(jìn)行語(yǔ)音合成并發(fā)音了,對(duì)應(yīng)的API為
public int speak (String text, int queueMode, HashMap