Closed8

「eSpeak NG」を試す

kun432kun432

間接的に使ってるケースはあると思うけど、直接触ったことがない。温故知新ということで。

GitHubレポジトリ

https://github.com/espeak-ng/espeak-ng

eSpeak NG Text-to-Speech

eSpeak NG は、Linux、Windows、Android およびその他のオペレーティングシステム向けの、コンパクトなオープンソースのテキスト読み上げ合成ソフトウェアです。100以上の言語とアクセント に対応しており、Jonathan Duddington によって作成された eSpeak エンジンに基づいています。

eSpeak NG は「フォルマント合成」方式を採用しています。これにより、多くの言語を小容量で提供することが可能です。 発話は明瞭であり、高速動作でも利用できますが、人間の音声録音に基づく大型の合成器ほど自然または滑らかではありません。また、Klatt フォルマント合成および MBROLA をバックエンドの音声合成器として使用する機能もサポートしています。

eSpeak NG は以下の形態で提供されています:

  • コマンドライン プログラム(Linux および Windows)として、ファイルまたは標準入力からテキストを読み上げます。
  • 他のプログラムで利用するための 共有ライブラリ 版。(Windows では DLL です。)
  • Windows 用の SAPI5 版で、スクリーンリーダーや Windows SAPI5 インターフェースに対応した他のプログラムで利用できます。
  • eSpeak NG は Solaris や Mac OSX を含む他のプラットフォームにも移植されています。

機能

  • 様々な音声が含まれており、その特性は変更可能です。
  • 発話出力を WAV ファイルとして生成できます。
  • SSML (Speech Synthesis Markup Language) がサポートされています(完全ではありません)、および HTML もサポートしています。
  • コンパクトなサイズ。プログラムとそのデータ、並びに多くの言語を含めると、全体で数MB程度です。
  • MBROLA ディフォン音声 のフロントエンドとして利用可能です。 eSpeak NG は、ピッチと長さの情報を伴ってテキストを音素に変換します。
  • テキストを音素コードに変換することができ、他の音声合成エンジンのフロントエンドとして適用可能です。
  • 他の言語への対応の可能性があります。いくつかは進捗状況が異なる段階で含まれています。
    これらまたはその他の言語に関して、母語話者からの協力を歓迎します。
  • C 言語で記述されています。

各リリースおよび eSpeak NG プロジェクトの変更内容については、ChangeLog を参照してください。

以下のプラットフォームがサポートされています:

プラットフォーム 最小バージョン 状態
Linux CI
BSD
Android 4.0
Windows Windows 8
Mac

元々はこちらだそうで。

https://espeak.sourceforge.net/

kun432kun432

インストール

MacならHomebrewで。Linuxでも概ねパッケージで用意されているみたい。

brew install espeak-ng
espeak-ng --help
出力

eSpeak NG text-to-speech: 1.52.0  Data at: /opt/homebrew/Cellar/espeak-ng/1.52.0/share/espeak-ng-data

espeak-ng [options] ["<words>"]

-f <text file>   Text file to speak
--stdin    Read text input from stdin at once till to the end of a stream.

If neither -f nor --stdin are provided, then <words> from arguments are spoken,
or text is spoken from stdin, read separately one line by line at a time.

-a <integer>
	   Amplitude, 0 to 200, default is 100
-d <device>
	   Use the specified device to speak the audio on. If not specified, the
	   default audio device is used.
-g <integer>
	   Word gap. Pause between words, units of 10mS at the default speed
-k <integer>
	   Indicate capital letters with: 1=sound, 2=the word "capitals",
	   higher values indicate a pitch increase (try -k20).
-l <integer>
	   Line length. If not zero (which is the default), consider
	   lines less than this length as end-of-clause
-p <integer>
	   Pitch adjustment, 0 to 99, default is 50
-P <integer>
	   Pitch range adjustment, 0 to 99, default is 50
-s <integer>
	   Speed in approximate words per minute. The default is 175
-v <voice name>
	   Use voice file of this name from espeak-ng-data/voices
-w <wave file name>
	   Write speech to this WAV file, rather than speaking it directly
-b	   Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit
-m	   Interpret SSML markup, and ignore other < > tags
--ssml-break=<percentage>
	   Set SSML break time multiplier, default is 100
-q	   Quiet, don't produce any speech (may be useful with -x)
-x	   Write phoneme mnemonics to stdout
-X	   Write phonemes mnemonics and translation trace to stdout
-z	   No final sentence pause at the end of the text
-D	   Enable deterministic random mode
--compile=<voice name>
	   Compile pronunciation rules and dictionary from the current
	   directory. <voice name> specifies the language
--compile-debug=<voice name>
	   Compile pronunciation rules and dictionary from the current
	   directory, including line numbers for use with -X.
	   <voice name> specifies the language
--compile-mbrola=<voice name>
	   Compile an MBROLA voice
--compile-intonations
	   Compile the intonation data
--compile-phonemes=<phsource-dir>
	   Compile the phoneme data using <phsource-dir> or the default phsource directory
--ipa      Write phonemes to stdout using International Phonetic Alphabet
--path="<path>"
	   Specifies the directory containing the espeak-ng-data directory
--pho      Write mbrola phoneme data (.pho) to stdout or to the file in --phonout
--phonout="<filename>"
	   Write phoneme output from -x -X --ipa and --pho to this file
--punct="<characters>"
	   Speak the names of punctuation characters during speaking.  If
	   =<characters> is omitted, all punctuation is spoken.
--sep=<character>
	   Separate phonemes (from -x --ipa) with <character>.
	   Default is space, z means ZWJN character.
--split=<minutes>
	   Starts a new WAV file every <minutes>.  Used with -w
--stdout   Write speech output to stdout
--tie=<character>
	   Use a tie character within multi-letter phoneme names.
	   Default is U+361, z means ZWJ character.
--version  Shows version number and date, and location of espeak-ng-data
--voices=<language>
	   List the available voices for the specified language.
	   If <language> is omitted, then list all voices.
--load     Load voice from a file in current directory by name.
-h, --help Show this help.
kun432kun432

CLIでの利用

CLIのオプションは上でも出力してるけど、ドキュメントは以下。

https://github.com/espeak-ng/espeak-ng/tree/master/src/espeak-ng.1.ronn

利用可能な音声の一覧は以下

espeak-ng --voices
出力
Pty Language       Age/Gender VoiceName          File                 Other Languages
 5  af              --/M      Afrikaans          gmw/af
 5  am              --/M      Amharic            sem/am
 5  an              --/M      Aragonese          roa/an
 5  ar              --/M      Arabic             sem/ar
 5  as              --/M      Assamese           inc/as
 5  az              --/M      Azerbaijani        trk/az
 5  ba              --/M      Bashkir            trk/ba
 5  be              --/M      Belarusian         zle/be
 5  bg              --/M      Bulgarian          zls/bg
 5  bn              --/M      Bengali            inc/bn
 5  bpy             --/M      Bishnupriya_Manipuri inc/bpy
 5  bs              --/M      Bosnian            zls/bs
 5  ca              --/M      Catalan            roa/ca
 5  ca-ba           --/M      Catalan_(Balearic) roa/ca-ba
 5  ca-nw           --/M      Catalan_(North-western) roa/ca-nw
 5  ca-va           --/M      Catalan_(Valencian) roa/ca-va
 5  chr-US-Qaaa-x-west --/M      Cherokee_          iro/chr
 5  cmn             --/M      Chinese_(Mandarin,_latin_as_English) sit/cmn              (zh-cmn 5)(zh 5)
 5  cmn-latn-pinyin --/M      Chinese_(Mandarin,_latin_as_Pinyin) sit/cmn-Latn-pinyin  (zh-cmn 5)(zh 5)
 5  cs              --/M      Czech              zlw/cs
 5  cv              --/M      Chuvash            trk/cv
 5  cy              --/M      Welsh              cel/cy
 5  da              --/M      Danish             gmq/da
 5  de              --/M      German             gmw/de
 5  el              --/M      Greek              grk/el
 5  en-029          --/M      English_(Caribbean) gmw/en-029           (en 10)
 2  en-gb           --/M      English_(Great_Britain) gmw/en               (en 2)
 5  en-gb-scotland  --/M      English_(Scotland) gmw/en-GB-scotland   (en 4)
 5  en-gb-x-gbclan  --/M      English_(Lancaster) gmw/en-GB-x-gbclan   (en-gb 3)(en 5)
 5  en-gb-x-gbcwmd  --/M      English_(West_Midlands) gmw/en-GB-x-gbcwmd   (en-gb 9)(en 9)
 5  en-gb-x-rp      --/M      English_(Received_Pronunciation) gmw/en-GB-x-rp       (en-gb 4)(en 5)
 5  en-shaw         --/M      English_(Shavian_alphabet) gmw/en-Shaw
 2  en-us           --/M      English_(America)  gmw/en-US            (en 3)
 5  en-us-nyc       --/M      English_(America,_New_York_City) gmw/en-US-nyc
 5  eo              --/M      Esperanto          art/eo
 5  es              --/M      Spanish_(Spain)    roa/es
 5  es-419          --/M      Spanish_(Latin_America) roa/es-419           (es-mx 6)
 5  et              --/M      Estonian           urj/et
 5  eu              --/M      Basque             eu
 5  fa              --/M      Persian            ira/fa
 5  fa-latn         --/M      Persian_(Pinglish) ira/fa-Latn
 5  fi              --/M      Finnish            urj/fi
 5  fo              --/M      Faroese            gmq/fo
 5  fr-be           --/M      French_(Belgium)   roa/fr-BE            (fr 8)
 5  fr-ch           --/M      French_(Switzerland) roa/fr-CH            (fr 8)
 5  fr-fr           --/M      French_(France)    roa/fr               (fr 5)
 5  ga              --/M      Gaelic_(Irish)     cel/ga
 5  gd              --/M      Gaelic_(Scottish)  cel/gd
 5  gn              --/M      Guarani            sai/gn
 5  grc             --/M      Greek_(Ancient)    grk/grc
 5  gu              --/M      Gujarati           inc/gu
 5  hak             --/M      Hakka_Chinese      sit/hak
 5  haw             --/M      Hawaiian           map/haw
 5  he              --/M      Hebrew             sem/he
 5  hi              --/M      Hindi              inc/hi
 5  hr              --/M      Croatian           zls/hr               (hbs 5)
 5  ht              --/M      Haitian_Creole     roa/ht
 5  hu              --/M      Hungarian          urj/hu
 5  hy              --/M      Armenian_(East_Armenia) ine/hy               (hy-arevela 5)
 5  hyw             --/M      Armenian_(West_Armenia) ine/hyw              (hy-arevmda 5)(hy 8)
 5  ia              --/M      Interlingua        art/ia
 5  id              --/M      Indonesian         poz/id
 5  io              --/M      Ido                art/io
 5  is              --/M      Icelandic          gmq/is
 5  it              --/M      Italian            roa/it
 5  ja              --/M      Japanese           jpx/ja
 5  jbo             --/M      Lojban             art/jbo
 5  ka              --/M      Georgian           ccs/ka
 5  kaa             --/M      Karakalpak         trk/kaa
 5  kk              --/M      Kazakh             trk/kk
 5  kl              --/M      Greenlandic        esx/kl
 5  kn              --/M      Kannada            dra/kn
 5  ko              --/M      Korean             ko
 5  kok             --/M      Konkani            inc/kok
 5  ku              --/M      Kurdish            ira/ku
 5  ky              --/M      Kyrgyz             trk/ky
 5  la              --/M      Latin              itc/la
 5  lb              --/M      Luxembourgish      gmw/lb
 5  lfn             --/M      Lingua_Franca_Nova art/lfn
 5  lt              --/M      Lithuanian         bat/lt
 5  ltg             --/M      Latgalian          bat/ltg
 5  lv              --/M      Latvian            bat/lv
 5  mi              --/M      Māori             poz/mi
 5  mk              --/M      Macedonian         zls/mk
 5  ml              --/M      Malayalam          dra/ml
 5  mr              --/M      Marathi            inc/mr
 5  ms              --/M      Malay              poz/ms
 5  mt              --/M      Maltese            sem/mt
 5  mto             --/M      Totontepec_Mixe    miz/mto
 5  my              --/M      Myanmar_(Burmese)  sit/my
 5  nb              --/M      Norwegian_Bokmål  gmq/nb               (no 5)
 5  nci             --/M      Nahuatl_(Classical) azc/nci
 5  ne              --/M      Nepali             inc/ne
 5  nl              --/M      Dutch              gmw/nl
 5  nog             --/M      Nogai              trk/nog
 5  om              --/M      Oromo              cus/om
 5  or              --/M      Oriya              inc/or
 5  pa              --/M      Punjabi            inc/pa
 5  pap             --/M      Papiamento         roa/pap
 5  piqd            --/M      Klingon            art/piqd
 5  pl              --/M      Polish             zlw/pl
 5  pt              --/M      Portuguese_(Portugal) roa/pt               (pt-pt 5)
 5  pt-br           --/M      Portuguese_(Brazil) roa/pt-BR            (pt 6)
 5  py              --/M      Pyash              art/py
 5  qdb             --/M      Lang_Belta         art/qdb
 5  qu              --/M      Quechua            qu
 5  quc             --/M      K'iche'            myn/quc
 5  qya             --/M      Quenya             art/qya
 5  ro              --/M      Romanian           roa/ro
 5  ru              --/M      Russian            zle/ru
 5  ru-cl           --/M      Russian_(Classic)  zle/ru-cl
 2  ru-lv           --/M      Russian_(Latvia)   zle/ru-LV
 5  sd              --/M      Sindhi             inc/sd
 5  shn             --/M      Shan_(Tai_Yai)     tai/shn
 5  si              --/M      Sinhala            inc/si
 5  sjn             --/M      Sindarin           art/sjn
 5  sk              --/M      Slovak             zlw/sk
 5  sl              --/M      Slovenian          zls/sl
 5  smj             --/M      Lule_Saami         urj/smj
 5  sq              --/M      Albanian           ine/sq
 5  sr              --/M      Serbian            zls/sr
 5  sv              --/M      Swedish            gmq/sv
 5  sw              --/M      Swahili            bnt/sw
 5  ta              --/M      Tamil              dra/ta
 5  te              --/M      Telugu             dra/te
 5  th              --/M      Thai               tai/th
 5  ti              --/M      Tigrinya           sem/ti
 5  tk              --/M      Turkmen            trk/tk
 5  tn              --/M      Setswana           bnt/tn
 5  tr              --/M      Turkish            trk/tr
 5  tt              --/M      Tatar              trk/tt
 5  ug              --/M      Uyghur             trk/ug
 5  uk              --/M      Ukrainian          zle/uk
 5  ur              --/M      Urdu               inc/ur
 5  uz              --/M      Uzbek              trk/uz
 5  vi              --/M      Vietnamese_(Northern) aav/vi
 5  vi-vn-x-central --/M      Vietnamese_(Central) aav/vi-VN-x-central
 5  vi-vn-x-south   --/M      Vietnamese_(Southern) aav/vi-VN-x-south
 5  xex             --/M      xextan-test        art/xex
 5  yue             --/M      Chinese_(Cantonese) sit/yue              (zh-yue 5)(zh 8)
 5  yue             --/M      Chinese_(Cantonese,_latin_as_Jyutping) sit/yue-Latn-jyutping (zh-yue 5)(zh 8)

特定の言語で利用可能な音声の一覧。日本語の場合。

espeak-ng --voices=ja
出力
Pty Language       Age/Gender VoiceName          File                 Other Languages
 1  ja              --/M      japanese-mbrola-1  mb/mb-jp1
 2  ja              --/F      japanese-mbrola-2  mb/mb-jp2
 3  ja              --/F      japanese-mbrola-3  mb/mb-jp3
 5  ja              --/M      Japanese           jpx/ja

4つ利用可能なようだが、mbrolaとあるのが、MBROLA音声合成に対応した音声らしい。MBROLAについては以下が詳しかった。

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0250

で、以下のドキュメントにもあるけど、

https://github.com/espeak-ng/espeak-ng/tree/master/docs/mbrola.md

The MBROLA is an open source speech engine with collection of diphone voices for speech synthesis. Voices are cost-free for non-commerical purposes, but are not open source.

この点には注意が必要かな。

とりあえず喋らせてみる。まずは英語で。

espeak-ng "Hello. It's a beautiful day, isn't it?"

https://audio.com/kun432/audio/en1

いかにもな機械音声になっている。

別の音声を指定する場合は-vで音声ファイル名を指定する。

espeak-ng -v gmw/en-029  "Hello. It's a beautiful day, isn't it?"

https://audio.com/kun432/audio/gmw-en-029

MBROLA音声合成に対応した音声も試してみたのだが、

espeak-ng -v mb/mb-us1  "Hello. It's a beautiful day, isn't it?"
出力
Cannot find MBROLA voice file 'us1' in neither of paths:
 - $data_dir/mbrola/us1
 - $data_dir/mbrola/us1/us1
 - $data_dir/mbrola/voices/us1
for any data_dir in XDG_DATA_DIRS=/usr/local/share:/usr/share
Please install necessary MBROLA voice!
mbrowrap error: /proc is unaccessible: No such file or directory
Error: Could not load the specified mbrola voice file.

色々調べてみたのだけども、どうやらMacの場合は少なくともソースからビルドしないとだめっぽい感じに見える。

https://github.com/espeak-ng/espeak-ng/issues?q=state%3Aopen label%3A"portability%2Fmac"

kun432kun432

ということで、ここからはLinuxに変える。Ubuntu-22.04。

sudo apt install espeak-ng mbrola

MBROLAの各音声は別々のパッケージにわかれているようなので、個別にインストールする。全部は面倒なので、英語と日本語をいくつか。

sudo apt install mbrola-us1 mbrola-us2 mbrola-us3 mbrola-jp1 mbrola-jp2 mbrola-jp3

MBROLAの英語を試してみる。

espeak-ng -v mb/mb-us1 "Hello. It's a beautiful day, isn't it?"
espeak-ng -v mb/mb-us2 "Hello. It's a beautiful day, isn't it?"

https://audio.com/kun432/audio/mb-us1

https://audio.com/kun432/audio/mb-us2

機械音声ではあるが、最初のサンプルよりはいくぶんマシなように思える。

kun432kun432

ということで日本語。

espeak-ng -v jpx/ja "こんにちは。今日はいいお天気ですね。"

https://audio.com/kun432/audio/jpx-ja

どうやら漢字は読めないみたい。かなで指定してみる。

espeak-ng -v jpx/ja "こんにちは。きょうはいいおてんきですね。"

https://audio.com/kun432/audio/jpx-ja-kana

「は」をそのまま読んでたりするが、こういうものみたい。

MBROLAの日本語も試してみる。-wでWAVファイルに出力できる。

espeak-ng -v mb/mb-jp1 -w mb-jp1.wav "こんにちは。きょうはいいおてんきですね。"
espeak-ng -v mb/mb-jp2 -w mb-jp2.wav "こんにちは。きょうはいいおてんきですね。"
espeak-ng -v mb/mb-jp3 -w mb-jp3.wav "こんにちは。きょうはいいおてんきですね。"

こんなWarningが出るが、一応出力はされる。

出力
mbrola: Warning: n-n unknown, replaced with _-_

https://audio.com/kun432/audio/mb-jp1

https://audio.com/kun432/audio/mb-jp2

https://audio.com/kun432/audio/mb-jp3

かなり途切れている感がある。

kun432kun432

-xをつけると音素が取得できる。

英語

espeak-ng -x "Hello. It's a beautiful day, isn't it?"
出力
h@l'oU
Its a# bj'u:tif@L d'eI
'Iz@nt It

日本語

espeak-ng -v jpx/ja -x "こんにちは。きょうはいいおてんきですね。"
出力
k,onnit_s\'iha
k_j,ouh,ai:,oteNk,ides'une

-Xでより詳細に出力できる。

espeak-ng -v jpx/ja -X "こんにちは。きょうはいいおてんきですね。"
出力
Translate 'こんにちは'
 36	こ      [ko]

 56	ん (L1  [n]
 36	ん      [N\]

 36	に      [ni]

 36	ち      [t_s\i]

 36	は      [ha]

k,onnit_s\'iha
Replace: で > で
Translate 'きょうはいいおてんきですね'
 36	き      [ki]
 56	き (L2  [k_j]

 36	ょ      [o]

 36	う      [u]

 36	は      [ha]

 36	い      [i]
 57	いい   [i:]

 36	お      [o]

 36	て      [te]

 56	ん (L0  [N]
 36	ん      [N\]

 36	き      [ki]

 36	て      [te]
 57	で   [de]

 36	す      [su]

 36	ね      [ne]

k_j,ouh,ai:,oteNk,ides'une

なお、音素で発話テキストを指定することもできる。[[〜]]で囲めば良いみたい。

espeak-ng -x "[[h@l'oU]]"
espeak-ng -v jpx/ja "[[k,onnit_s\'iwa]]"    # 「は」を「わ」に変えている
kun432kun432

まとめ

今となっては古き良き音声合成という感じなのだけど、最近のTTSでも依存パッケージにチラホラ見かけるのは、ここなんだろうね。

  • MBROLA ディフォン音声 のフロントエンドとして利用可能です。 eSpeak NG は、ピッチと長さの情報を伴ってテキストを音素に変換します。
  • テキストを音素コードに変換することができ、他の音声合成エンジンのフロントエンドとして適用可能です。

日本語の場合だと、このあたりはpyopenjtalkでやることが多いかなというところ。

https://zenn.dev/kun432/scraps/ad1d1ed8b90eea

このスクラップは2025/02/16にクローズされました