close

撰寫: 2022/2/5

發佈: 2022/5/16

Raspberry Pi使用eSpeak

eSpeak是一個精簡且開源的語音合成軟體,可支援英語與其他語言在LinusWindows作業系統的環境中使用,所以適合Raspberry PiLinus作業系統讓它可以說出你想要的語言,當然eSpeak也被轉到Android, Mac OSX and SolarisLinus作業系統。

在官網http://espeak.sourceforge.net如下圖可以看到它的功能與特色如下:

image

  • A command line program (Linux and Windows) to speak text from a file or from stdin.
    Linux and Windows在作業系統下以command line program的方式執行說出文字,來源可從檔案或直接從stdin來。
  • Includes different Voices, whose characteristics can be altered.
    包括不同種類的聲音(如男人、女人等),這些聲音特質是可以調整轉換的。
  • Can produce speech output as a WAV file.
    可以藉eSpeak產生的說話語音輸出為WAV檔。
  • SSML (Speech Synthesis Markup Language) is supported (not complete), and also HTML.
    可支援(並非百分之百完全支援) SSML Speech Synthesis Markup Language語音合成標記語法,並且包括網頁用的HTML語法。
  • Compact size. The program and its data, including many languages, totals about 2 Mbytes.
    精簡的大小;程式加資料(甚至包含多個語言)總共約2 Mbytes
  • Can translate text into phoneme codes, so it could be adapted as a front end for another speech synthesis engine.
    可以轉換文字成為聲音元素phonemes碼,所以它可以加成在其他語言合成引擎的前端。
  • Can be used as a front-end to MBROLA diphone voices, see mbrola.html. eSpeak converts text to phonemes with pitch and length information.
    可以應用在MBROLA diphone voices雙音節聲音產生的前端,由eSpeak轉換文字成為有音高pitch及長度資訊的聲音元素phonemes,再交給MBROLA產生語言。
  • Potential for other languages. Several are included in varying stages of progress. Help from native speakers for these or other languages is welcome.
    有潛力開發各種其他語言,目前已經有多種語言在進行到不同變動的程度,這些不同語言原生講者想來幫忙都相當歡迎。
  • Development tools are available for producing and tuning phoneme data.
    現已有可以產生及調整聲音元素資料的開發工具。
  • Written in C.
    採用C語言開發。

    在此可以看到eSpeak是執行程式而非以Python lib形式來呼叫執行,安裝後是在作業系統下以command line program的方式執行;為了增加eSpeak語音的品質及可由Python來呼叫執行,所以在此安裝除了eSpeak本身之外總共包括以下三個步驟:

  • eSpeak
  • MBROLA
  • Python call

 

eSpeak安裝

Linus下安裝eSpeak透過apt-get如下:

pi@raspberrypi:~ $ sudo apt-get install espeak

正在讀取套件清單... 完成

正在重建相依關係         

正在讀取狀態資料... 完成

下列的額外套件將被安裝:

  espeak-data libespeak1 libportaudio2 libsonic0

下列【新】套件將會被安裝:

  espeak espeak-data libespeak1 libportaudio2 libsonic0

升級 0 個,新安裝 5 個,移除 0 個,有 0 個未被升級。

需要下載 1,217 kB 的套件檔。

此操作完成之後,會多佔用 2,974 kB 的磁碟空間。

是否繼續進行 [Y/n] [Y/n] y

下載:1 http://mirror.ossplanet.net/raspbian/raspbian buster/main armhf libportaudio2 armhf 19.6.0-1+deb10u1 [56.7 kB]

下載:2 http://mirror.ossplanet.net/raspbian/raspbian buster/main armhf libsonic0 armhf 0.2.0-7 [9,888 B]

下載:3 http://mirror.ossplanet.net/raspbian/raspbian buster/main armhf espeak-data armhf 1.48.04+dfsg-7+deb10u1 [941 kB]

下載:4 http://mirror.ossplanet.net/raspbian/raspbian buster/main armhf libespeak1 armhf 1.48.04+dfsg-7+deb10u1 [139 kB]

下載:5 http://mirror.ossplanet.net/raspbian/raspbian buster/main armhf espeak armhf 1.48.04+dfsg-7+deb10u1 [70.6 kB]

取得 1,217 kB 用了 4s (287 kB/s)

選取了原先未選的套件 libportaudio2:armhf

(讀取資料庫 ... 目前共安裝了 98949 個檔案和目錄。)

正在準備解包 .../libportaudio2_19.6.0-1+deb10u1_armhf.deb……

Unpacking libportaudio2:armhf (19.6.0-1+deb10u1) ...

選取了原先未選的套件 libsonic0:armhf

正在準備解包 .../libsonic0_0.2.0-7_armhf.deb……

Unpacking libsonic0:armhf (0.2.0-7) ...

選取了原先未選的套件 espeak-data:armhf

正在準備解包 .../espeak-data_1.48.04+dfsg-7+deb10u1_armhf.deb……

Unpacking espeak-data:armhf (1.48.04+dfsg-7+deb10u1) ...

選取了原先未選的套件 libespeak1:armhf

正在準備解包 .../libespeak1_1.48.04+dfsg-7+deb10u1_armhf.deb……

Unpacking libespeak1:armhf (1.48.04+dfsg-7+deb10u1) ...

選取了原先未選的套件 espeak

正在準備解包 .../espeak_1.48.04+dfsg-7+deb10u1_armhf.deb……

Unpacking espeak (1.48.04+dfsg-7+deb10u1) ...

設定 libportaudio2:armhf (19.6.0-1+deb10u1) ...

設定 libsonic0:armhf (0.2.0-7) ...

設定 espeak-data:armhf (1.48.04+dfsg-7+deb10u1) ...

設定 libespeak1:armhf (1.48.04+dfsg-7+deb10u1) ...

設定 espeak (1.48.04+dfsg-7+deb10u1) ...

執行 man-db (2.8.5-2) 的觸發程式……

執行 libc-bin (2.28-10+rpt2+rpi1) 的觸發程式……

#Set voice data

copy from source/espeak-data to /home/pi/espeak-data

system copy on another path:

/usr/lib/arm-linux-gnueabihf/espeak-data

*voices

*mbrola: if install mbola

Default setting on /home/pi/espeak-data/voices/default

 name default

 language en

 gender male

pi@raspberrypi:~ $

 

安裝完可以看到初始語言為language en英文,聲音種類特徵為gender male男性;可以簡單在command line輸入以下命令測試eSpeak

pi@raspberrypi:~ $ espeak “Hello World”

若安裝完成應該在Raspberry Pi 喇叭可以聽到輸入的文字。

 

MBROLA安裝

安裝MBROLA較為麻煩,因為要從c原始碼開始來安裝,所以需要以下7 步驟如下:

  • Step1:安裝gcc

pi@raspberrypi:~ $ sudo apt-get install git make gcc

正在讀取套件清單... 完成

正在重建相依關係         

正在讀取狀態資料... 完成

gcc is already the newest version (4:8.3.0-1+rpi2).

gcc 被設定為手動安裝。

git is already the newest version (1:2.20.1-2+deb10u3).

make is already the newest version (4.2.1-1.2).

make 被設定為手動安裝。

升級 0 個,新安裝 0 個,移除 0 個,有 0 個未被升級。

因為原來就已經有安裝gcc,所以在此並沒有再做升級。

 

  • Step2: GitHub下載

pi@raspberrypi:~ $ git clone https://github.com/numediart/MBROLA.git

Cloning into 'MBROLA'...

remote: Enumerating objects: 283, done.

remote: Total 283 (delta 0), reused 0 (delta 0), pack-reused 283

Receiving objects: 100% (283/283), 403.59 KiB | 184.00 KiB/s, done.

Resolving deltas: 100% (143/143), done.

 

  • Step3: 編譯 make

pi@raspberrypi:~ $ cd MBROLA

pi@raspberrypi:~/MBROLA $ make

if [ ! -d Bin/Standalone ]; then \

mkdir Bin ; mkdir Bin/LibOneChannel; mkdir Bin/LibMultiChannel ; mkdir Bin/Standalone ; mkdir Bin/Standalone/Standalone ; mkdir Bin/Standalone/Parser ; mkdir Bin/Standalone/Engine ;         mkdir Bin/Standalone/Database ;         mkdir Bin/Standalone/Misc; \

fi

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Standalone/synth.o -c Standalone/synth.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Engine/mbrola.o -c Engine/mbrola.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Engine/diphone.o -c Engine/diphone.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Parser/phone.o -c Parser/phone.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Parser/parser_input.o -c Parser/parser_input.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Parser/input_file.o -c Parser/input_file.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Parser/phonbuff.o -c Parser/phonbuff.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Misc/audio.o -c Misc/audio.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Misc/vp_error.o -c Misc/vp_error.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Misc/mbralloc.o -c Misc/mbralloc.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Misc/common.o -c Misc/common.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/database.o -c Database/database.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/database_old.o -c Database/database_old.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/diphone_info.o -c Database/diphone_info.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/little_big.o -c Database/little_big.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/hash_tab.o -c Database/hash_tab.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/zstring_list.o -c Database/zstring_list.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/rom_handling.o -c Database/rom_handling.c

gcc  -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL  -o Bin/Standalone/Database/rom_database.o -c Database/rom_database.c

gcc -DLITTLE_ENDIAN -ansi -pedantic -IParser -IStandalone -IMisc -ILibOneChannel -ILibMultiChannel -IEngine -IDatabase -Wall -DROMDATABASE_STORE -DROMDATABASE_INIT -DSIGNAL   -o ./Bin/mbrola Bin/Standalone/Standalone/synth.o Bin/Standalone/Engine/mbrola.o Bin/Standalone/Engine/diphone.o Bin/Standalone/Parser/phone.o Bin/Standalone/Parser/parser_input.o Bin/Standalone/Parser/input_file.o Bin/Standalone/Parser/phonbuff.o Bin/Standalone/Misc/audio.o Bin/Standalone/Misc/vp_error.o Bin/Standalone/Misc/mbralloc.o Bin/Standalone/Misc/common.o Bin/Standalone/Database/database.o Bin/Standalone/Database/database_old.o Bin/Standalone/Database/diphone_info.o Bin/Standalone/Database/little_big.o Bin/Standalone/Database/hash_tab.o Bin/Standalone/Database/zstring_list.o Bin/Standalone/Database/rom_handling.o Bin/Standalone/Database/rom_database.o -lm

pi@raspberrypi:~/MBROLA $

 

  • Step4: 安裝

    只要將make完成的檔案mbrola放到/usr/bin/下就完成安裝,執行以下的命令:

pi@raspberrypi:~/MBROLA $ sudo cp /home/pi/MBROLA/Bin/mbrola /usr/bin/mbrola

 

  • Step5: 建立語音種類共同目錄

    在系統建立usr/share/mbrola目錄,執行以下的命令:

pi@raspberrypi:~/MBROLA $ sudo mkdir /usr/share/mbrola

 

  • Step6: gitHub所需要的語音

    在共同目錄下創建需要使用語音目錄,gitHub所需要的語音,在此以英文語音為例,執行以下的命令:

pi@raspberrypi:~/MBROLA $ sudo mkdir /usr/share/mbrola/us1

download us1 voice and copy it over the us1 directory from

https://github.com/numediart/MBROLA-voices

download from web us1,us2,us3

pi@raspberrypi:~/MBROLA $ sudo cp us1 /usr/share/mbrola/us1

 

  • Step7: 測試mbrola

    安裝完成MBROLA可以執行以下的命令來進行測試:

pi@raspberrypi:~/MBROLA $ espeak "create a direction with the same name"

這時應該聽到eSpeak原來初始設定的聲音。但若改為以下命令:

pi@raspberrypi:~/MBROLA $ espeak -v mb-us1 "create a direction with the same name"

這時應該聽到MBROLA提供的的聲音,各位應該可以聽出來有明顯不同。

 

Python 呼叫

既然eSpeak已經安裝到系統中,只要在系統的command line呼叫espeak就可以執行eSpeak產生語音;所以要在Python中使用eSpeak可以很簡單利用cmdLine.run就可達到同樣的方法如下:

import subprocess as cmdLine

cmdLine.run("clear")

 

# Define the words to speak

speech = "Good morning, it is nice day"

 

# Construct the command line

command = 'espeak -x -v ' + 'mb-us1 ' + chr(34) + speech + chr(34)

# more Phoneme detail result

#command = 'espeak -X -v ' + 'mb-us1 ' + chr(34) + speech + chr(34)

print (command)

print ("")

 

# Run espeak

#cmdLine.run(command, shell=True)

result = cmdLine.run(command, shell=True, capture_output=True, text=True)

 

# Print the terminal result

print("Phoneme Results:")

print(result.stdout)

輸出結果如下:

>>>

TERM environment variable not set.

espeak -x -v mb-us1 "Good morning, it is nice day"

 

 g'Ud m'O@nIN

 It Iz n'aIs d'eI

 

 

另外也可在Python中可以撰寫eSpeak函式庫程式,爾後只需要加入eSpeak函式庫,就可簡易的執行eSpeak呼叫功能。此eSpeak函式庫程式如下:

# Import subprocess to execute the espeak termnial commands

import subprocess as cmdLine

 

# Name the class:

class eSpeak:

 

    # __init___

    def __init__(self, voice='mb-us1'):

        self.voice = voice

       

    # Speak the text

    def say(self, speech):

        # define the command line

        command = 'espeak -v ' + self.voice + " " + chr(34) + speech + chr(34)

        # Execute the command in term terminal

        cmdLine.run(command, shell=True, capture_output=True, text=True)

 

    # Prints phonemes using -X or -x (-q means quiet no speaking)

    # You still need to assign -v here  for the dictionary reference

    def phonemes(self, speech, phone):

        command = 'espeak -' + phone + ' -q -v ' + self.voice + " " + chr(34) + speech + chr(34)

        result = cmdLine.run(command, shell=True, capture_output=True, text=True)

        # Return result

        return result.stdout

   

    # Sends the speech out to a wav file named by filename

    def wavFile(self, speech, filename):

        command = 'espeak -w ' + filename + ' -v ' + self.voice + " " + chr(34) + speech + chr(34)

        cmdLine.run(command, shell=True, capture_output=True, text=True)

   

    # Speech out a text file named by filename

    def textFile(self, filename):

        command = 'espeak -f ' + filename + ' -v ' + self.voice

        cmdLine.run(command, shell=True, capture_output=True, text=True)

 

後記

本文為個人學習的經驗,後續有所改進將再發文分享;本人因工作因素發文後並不會經常檢視讀者問題,對於沒法及時回覆問題敬請見諒!

若覺本文對讀者有所幫助,可回覆感想及你的分享!謝謝!

arrow
arrow
    文章標籤
    raspberry pi 樹莓 raspbian
    全站熱搜

    Philip4G 發表在 痞客邦 留言(2) 人氣()