翻譯:Derry / 2010-7-27
原文:http://www.xenocafe.com/tutorials/php/festival_text_to_speech/index.php
前提條件
基於*nix的操作系統
Festival for Linux
PHP 3 or higher
LAME Ain't an MP3 Encoder (optional)
下載源碼: festival-tts.tar.gz
內容
介紹
使用yum安裝Festival RPM
嘗試Festival Text-To-Speech功能
使用text2wave將TTS語音保存到磁盤
安裝LAME MP3編碼器
將WAV-RIFF音頻文件轉換爲MP3格式
爲Festival構建PHP前端(text2wave)
PHP TTS演示程序
結論
介紹
本教程將向你展示在Linux下如何使用Festival程序實現“文本-語音(TTS)”合成。Festival是類Unix系統下免費的軟件框架,它能夠將純文本轉換爲聽得見的語音輸出。可以確信我們幾乎都見到過微軟Merlin字符(也稱爲Microsoft Agent),它是微軟Office及其他產品的成員之一。我不能確信那就是Merlin字符首次登場的地方,但我可以肯定的是,它的確可以用來當作Office助手。MS代理使用語音合成技術爲本地應用提供更好的交互。我個人感覺這沒啥用,但的確有人喜歡它(Clippy比我更喜歡,但卻沒說一句話)。Linux下能夠使用Fesitval實現TTS。本文選擇的Linux系統是CentOS 4.2,但如果可以編譯Festival或者通過RPM加載(或者其他方式),任何類Unix操作系統都是可用的。在本教程裏,我將向你展示如下主題:使用yum安裝Festival,創建HTML表單來接收用戶輸入,同時使用PHP處理過程將輸入文本使用text2wave程序轉換爲聲音,也可以使用 LAME 把默認的WAV-RIFF文件轉換爲MP3來壓縮文件大小。實際上使用tts能夠實現的功能要比我這裏介紹的多的多, 所以到實踐中去學習,冒險多嘗試來創建更多有趣的Linux TTS應用吧(也許可以做個通過cron調用的語音提醒腳本?)。
使用yum安裝Festival RPM
本教程中安裝的是RPM版而非源碼格式的Festival,如果你願意通過源碼安裝,也可以在這兒下載. 採用源碼安裝是更好的選擇,原因在於Festival已經發布了1.95(2.0beta)版,而CentOS 4.x RPM的festival-1.4.2-25.i386.rpm版本是1.4.2. 我沒試過源碼安裝,所以只能推測它優化了tts合成引擎,但就本教程來講,RPM版的已經足夠了。如果你不確定電腦上是否安裝了Festival,可以使用which或者rpm命令來驗證一下。
which festival
可以看到,沒有找到任何Festival信息。這基本上意味着你沒有安裝,但如果你想嘗試rpm,那麼試試這個命令:
rpm -qa | grep -i festival
如果Festival RPM沒有顯示,那說明你沒安裝。沒問題,這裏正好用到yum,現在我們就使用yum安裝Festival:
yum install festival
yum將會與CentOS文檔庫通信,解析Festival和你操作系統上可能的依賴項,並提示你下載安裝Festival RPM。輸入 y 表示同意並按回車。Festival RPM有18M,所以在下載的時候你可能會想站起來伸個懶腰啥的。一旦下載完成,無須手動安裝,yum會幫你幹這個事兒。好了,完成Festival安裝後,下一步我們將使用它,讓計算機說話。
嘗試Festival Text-To-Speech功能
我們來通過幾個例子來看看怎麼使用Festival。你最好看看Festival用戶手冊頁面來獲取更多的可選項和使用方法。基本上,你只管使用--tts選項傳遞一個文本字符串給Festival,它就能把文本合成爲語音了。同樣也可以使用文本文件或者腳本來完成更加動態的音頻輸出。
例1: 美麗的一天消息(echo 文本)
echo "It's such a beautiful day! Why are you in front of the computer?" | festival --tts
例 2: 今天是幾號? (編程輸出)
date '+%A, %B %e, %Y' | festival --tts
例 3: 隨機日期 (PHP shell 腳本)
./rand.php | festival --tts
#!/usr/bin/php -q <?php // seed srand srand((double)microtime()*1000000); // what is the random number? echo "The random number for the day is " . rand(1,25); ?>
可以看到,給Festival發送文本是有很多種方式的。如果你花時間看了Festival 用戶手冊頁面 ,也許會注意到並沒有保存音頻輸出爲文件的選項。你將不能像把文本導出文件一樣把音頻輸出也導出文件,那該怎麼辦呢?在Festival包中有個程序叫做text2wave,它能夠把音頻以WAV格式保存爲磁盤文件。
使用text2wave將Text-To-Speech音頻保存到磁盤
text2wave讀取文本文件內容,將之轉換爲音頻語音,並保存爲ulaw,snd, aiff, riff, 或 nist 格式的音頻文件。 text2wave的默認音頻格式爲riff(或WAV,在Windows上很常見)。通過查看text2wave幫助(text2wave --help)可以看到相對Festival來說,它的選項就少多了,但至少你可以以echo,程序或者shell腳本來向它傳送文本。其中一個有用的選項是 -scale 用來做音量調節。默認的語音音量有些低,所以需要使用一個浮點值來提升它(50就足夠了)。
還是用上面那個例子,這裏爲每個例子創建一個WAV文件:
echo "It's such a beautiful day! Why are you in front of the computer?" | text2wave -scale 50 -o beautiful_day.wav
date '+%A, %B %e, %Y' | text2wave -scale 50 -o date.wav
./rand.php | text2wave -scale 50 -o rand.wav
如果輸入的文本過大,那麼輸出的WAV文件也會很大。可以嘗試使用其他text2wave支持的音頻格式或者使用LAME把WAV壓縮轉換爲MP3。下面我們就安裝LAME MP3 編碼器。
安裝LAME MP3編碼器
在安裝LAME之前要確保你係統上已經安裝了gcc等開發工具。如果沒安裝這些工具和一些依賴項,也可以使用yum(yum install gcc)來安裝。也可能有些軟件包沒有列出來,你也要逐個找出來。Lame 3.97beta2 是以源碼形式提供的。(從sourceforge獲取),也有RPM包可用,但本文我們將編譯源碼創建二進制文件。確認你一root用戶登錄並定位置home目錄,使用wget下載源碼包,解壓gzip壓縮後的tar包,cd到解壓後的lame-2.97目錄,運行configure腳本,make,然後安裝二進制文件。
su -
[enter root password]
cd ~
wget http://easynews.dl.sourceforge.net/sourceforge/lame/lame-3.97b2.tar.gz
tar zxvf lame-3.97b2.tar.gz
cd lame-3.97
./configure --prefix=/usr
make
make install
如果編譯沒有問題,從命令行運行LAME (lame)會有如下提示:
使用LAME我們可以把大個頭的WAV文件轉換爲體積更小巧的MP3版本。
將WAV-RIFF音頻文件轉換爲MP3格式
使用LAME相當簡易。你需要做的只是把WAV文件名傳給它,設置一個MP3輸出的文件名就行了。這兒我就不多介紹LAME的選項了,想看的話可以查看其手冊(man lame)。現在我們把前面三個例子生成的文件轉換爲MP3格式:
lame beautiful_day.wav beautiful_day.mp3
lame date.wav date.mp3
lame rand.wav rand.mp3
現在我們來比較一下WAV和MP3版本,文件大小差異很大,MP3的確是更好的選擇。
cd ~
ls -la *.wav
ls -la *.mp3
爲了強調一下迄今爲止我們所學的內容,這裏將創建一個PHP前端,這樣的話你就可以在瀏覽器上創建tts文件了。
爲Festival構建PHP前端(text2wave)
我們將通過創建HTML表單的方式來構建PHP前端處理tts。這個表單包括一個textarea(用來保存轉換語音的文本),文本輸入框(調節音量值)以及一個複選框(用來標識是否把WAV格式轉換爲MP3文件)。我在裏面加了很多註釋說明每塊代碼的用途,所以這兒就不再贅述了。你只需知道在文本框裏輸入一些文字,調整音量設置,然後選擇是否轉換爲MP3就行了。一旦你點擊了Text-To-Speech按鈕,表單將回發到服務器,表單上的數據將會被捕獲和處理。表單文本會被寫入到一個臨時文件,輸入到 text2wave 來轉換,text2wave會被PHP的exec函數調用。如果MP3選項被選中,第二個 exec 被調用,使用LAME完成WAV至MP3的轉換。當頁面重新加載後,在提交按鈕旁邊多出一個連接到音頻文件的超鏈接。可以點擊播放,或者右鍵單擊選擇“目標另存爲”來下載這個文件。
<?php // define the temporary directory // and where audio files will be written to after conversion $tmpdir = "/tmp"; $audiodir = "/change/to/your/path"; // if the Text-To-Speech button was click, process the data if (isset($_POST["make_audio"])) { $speech = stripslashes(trim($_POST["speech"])); $speech = substr($speech, 0, 1024); $volume_scale = intval($_POST["volume_scale"]); if ($volume_scale <= 0) { $volume_scale = 1; } if ($volume_scale > 100) { $volume_scale = 100; } if (intval($_POST["save_mp3"]) == 1) { $save_mp3 = true; } // continue only if some text was entered for conversion if ($speech != "") { // current date (year, month, day, hours, mins, secs) $currentdate = date("ymdhis",time()); // get micro seconds (discard seconds) list($usecs,$secs) = microtime(); // unique file name $filename = "{$currentdate}{$usecs}"; // other file names $speech_file = "{$tmpdir}/{$filename}"; $wave_file = "{$audiodir}/{$filename}.wav"; $mp3_file = "{$audiodir}/{$filename}.mp3"; // open the temp file for writing $fh = fopen($speech_file, "w+"); if ($fh) { fwrite($fh, $speech); fclose($fh); } // if the speech file exists, use text2wave if (file_exists($speech_file)) { // create the text2wave command and execute it $text2wave_cmd = sprintf("text2wave -o %s -scale %d %s",$wave_file,$volume_scale,$speech_file); exec($text2wave_cmd); // create an MP3 version? if ($save_mp3) { // create the lame command and execute it $lame_cmd = sprintf("lame %s %s",$wave_file,$mp3_file); exec($lame_cmd); // delete the WAV file to conserve space unlink($wave_file); } // delete the temp speech file unlink($speech_file); // which file name and type to use? WAV or MP3 $listen_file = (($save_mp3 == true) ? basename($mp3_file) : basename($wave_file)); $file_type = (($save_mp3 == true) ? "MP3" : "WAV"); // show audio file link $show_audio = true; } } } else { // default values $speech = "Hello there!"; $volume_scale = 50; $save_mp3 = true; } ?> <html> <head> <title>Festival: Linux Text-To-Speech Demo</title> <style type="text/css"> <!-- body { background-color:#ffffff; font-family:Arial, Helvetica, sans-serif; font-size:10pt; color: #000000; } h1 { font-family:Arial, Helvetica, sans-serif; font-size:18pt; color: #000000; } .tblfont { font-family:Arial, Helvetica, sans-serif; font-size:10pt; color: #000000; } --> </style> </head> <body> <h1>Linux Festival Text-To-Speech Demo</h1> <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> <table width="400" border="0" cellspacing="5" cellpadding="0" class="tblfont"> <tr> <td colspan="2"><textarea name="speech" wrap="VIRTUAL" style="width:350px;height:100px;"><?php echo $speech; ?></textarea></td> </tr> <tr> <td width="135">Volume Scale <input name="volume_scale" type="text" size="3" maxlength="3" value="<?php echo $volume_scale; ?>"> </td> <td width="265">Save as MP3 <input name="save_mp3" type="checkbox" value="1"<?php if ($save_mp3 == 1) { echo " checked"; } ?>> </td> </tr> <tr> <td><input name="make_audio" type="submit" value="Text-To-Speech"></td> <td> <?php if ($show_audio) { ?> <a href="audio/<?php echo $listen_file; ?>">Listen to the <?php echo $file_type; ?> file</a> <?php } ?> </td> </tr> </table> </form> </body> </html>
結論
就這些了,現在你有了在linux上使用Festival創建tts音頻文件的工具。使用tts合成技術你可以創造各種各樣的應用程序,例如提醒服務(通過向電話或Email發送音頻流)。Festival是個偉大的工具,但是有時候也會很難聽清楚語音的意思。對於某些特定的詞語它處理起來是有些問題,這對於商業應用來講顯得不是那麼完美。再來看看 AT&T 實驗室自然語音 Text-to-Speech 引擎 ,試試它們的 demo咋樣,它擁有商業級品質,聽起來真的很不錯,唯一不同的地方就是它是收費的。