Help us understand the problem. What is going on with this article?

ラテン語文を合成音声で読み上げる技術

More than 5 years have passed since last update.

こんにちは。@naoya_t です。

12/2の拙記事「ラテン語文解析プログラムを書くことを目的としたラテン語学習(前編)」で紹介した拙作解析ツール
https://github.com/naoyat/latin
では、MacOSXに搭載されている英文音声合成技術を利用して、ラテン語文を音読することが可能です。

この記事では、その辺りの事について語ってみたいと思います。

実装については speak_latin.py, latin/latin_syllable.py あたりをご覧ください。

デモ

$ echo "Cerēs erat dea frūmentī." | python latin.py -s

-s (--speech) が音読をONにするオプションです。

マクロン(長音記号)の入力が面倒なら、大文字を長音と認識させる -m (--capital-to-macron) オプションを使って

$ echo "vEnI, vIdI, vIcI." | python latin.py -m -s

のようにも使えます。

音声合成と発音

MacOSX の音声合成機能(text-to-speech)は今では英語以外の多くの言語での発話に対応していますが、細かい制御に対応しているのが(とりあえず手元のOS X 10.7.xでは)英語だけなので、発話したい内容を(北米)英語の発音記号に落としこむ必要があります。それぞれの音の高さ(周波数)や長さも設定する必要があります。

詳しくはApple社が公開している開発資料 https://developer.apple.com/library/mac/documentation/userexperience/conceptual/SpeechSynthesisProgrammingGuide/SpeechOverview/SpeechOverview.html#//apple_ref/doc/uid/TP40004365-CH3-SW6 辺りをご覧ください。

音素と長さ

ラテン語のアルファベットを、対応する音素の発音記号に置き換えます。

例:"Crētā" → k r EH t AA

EHAA は(k, r, t もそうですが)text-to-speech内部で用いられる音素表現です。

北米英語で用いられる音素に対応したものしか存在しないので、これを並べると何を喋っても北米訛りになる、という弱点が存在しますが、その点には目を瞑って頂ければ幸いです。

ちなみに母音の長短は(英語側で対応する短母音/長母音ではなく)音の長さで表しています。
(speak_latin.py の実装では、子音と短母音の長さを110msec、長母音の長さを220msecにしています。上の例では k, r, t が110msec、EH, AA が220msecです)

周波数(ピッチ)

ラテン語は高低アクセントなので、アクセントはとりあえず周波数の高低で表現することができます。

とりあえず、というのは、音声学的にどうこうというのはさておき、それっぽく聞こえるという精度を念頭においています。

アクセントはどこに来るのか

ラテン語では2音節語は最初の音節(=「paenultima 後ろから2番目の(音節)」)に、3音節語はpaenultimaの長短によって最初の音節ないし2番目の音節にアクセントが来ますので、アクセントが来る音節の周波数を他よりも高めに発声させます。

例: "Crētā" → C-rē-tā → C-[rē]-tā

speak_latin.py の実装では、低い方を135Hz(CとC#の間ぐらい?)、高い方をその4/3倍(低い音の4度上に相当)にしています。

音節の区切り方自体は概ね規則通りなので規則を実装します。(latin/latin_syllable.py)

  • lūx → lūx
  • caesar → cae-sar → [cae]-sar
  • cōnsulēs → cōn-su-lēs → [cōn]-su-lēs

発音制御コマンド列の生成

ここまで来ればラテン語の文を、(北米英語の)音素・長さ・ピッチ(周波数)の列に分解することができるので、text-to-speechの"TUNEフォーマット"(https://developer.apple.com/library/mac/documentation/userexperience/conceptual/SpeechSynthesisProgrammingGuide/FineTuning/FineTuning.html#//apple_ref/doc/uid/TP40004365-CH5-SW7 参照)で表現し、APIを叩くなり say コマンドに

[[inpt TUNE]] 発音制御コマンド列 [[inpt TEXT]]

のように投げるなりすれば発話が可能です。

例:"Crētā"

  k {D 110; P 135:0}
  r {D 110; P 180:0}
  EH {D 220; P 180:0}
  ~t {D 110; P 135:0}
  AA {D 220; P 135:0}
  % {D 110}

~ は前後の音素を一続きに読まないための記号で、% は無音を表します。

発音制御コマンド列の例

元のラテン語文:

In Crētā īnsulā māgnum labyrinthum Daedalus aedificāvit plēnum viārum flexuōsārum.

発音制御コマンド列:

tune.txt
[[inpt TUNE]]
   IY {D 110; P 135:0}
   n {D 110; P 135:0}
   % {D 110}

   k {D 110; P 135:0}
   r {D 110; P 180:0}
   EH {D 220; P 180:0}
   ~t {D 110; P 135:0}
   AA {D 220; P 135:0}
   % {D 110}

   IY {D 220; P 180:0}
   n {D 110; P 180:0}
   s {D 110; P 135:0}
   UW {D 110; P 135:0}
   l {D 110; P 135:0}
   AA {D 220; P 135:0}
   % {D 110}

   m {D 110; P 180:0}
   AA {D 220; P 180:0}
   g {D 110; P 180:0}
   n {D 110; P 135:0}
   UW {D 110; P 135:0}
   m {D 110; P 135:0}
   % {D 110}

   l {D 110; P 135:0}
   AA {D 110; P 135:0}
   b {D 110; P 135:0}
   yUW {D 110; P 135:0}
   r {D 110; P 180:0}
   IY {D 110; P 180:0}
   n {D 110; P 180:0}
   ~t {D 110; P 135:0}
   h {D 110; P 135:0}
   UW {D 110; P 135:0}
   m {D 110; P 135:0}
   % {D 110}

   d {D 110; P 180:0}
   AA {D 110; P 180:0}
   EH {D 110; P 180:0}
   d {D 110; P 135:0}
   AA {D 110; P 135:0}
   l {D 110; P 135:0}
   UW {D 110; P 135:0}
   s {D 110; P 135:0}
   % {D 110}

   AA {D 110; P 135:0}
   EH {D 110; P 135:0}
   d {D 110; P 135:0}
   IY {D 110; P 135:0}
   f {D 110; P 135:0}
   IY {D 110; P 135:0}
   k {D 110; P 180:0}
   AA {D 220; P 180:0}
   w {D 110; P 135:0}
   IY {D 110; P 135:0}
   ~t {D 110; P 135:0}
   % {D 110}

   p {D 110; P 180:0}
   l {D 110; P 180:0}
   EH {D 220; P 180:0}
   n {D 110; P 135:0}
   UW {D 110; P 135:0}
   m {D 110; P 135:0}
   % {D 110}

   w {D 110; P 180:0}
   IY {D 110; P 180:0}
   AA {D 220; P 180:0}
   r {D 110; P 135:0}
   UW {D 110; P 135:0}
   m {D 110; P 135:0}
   % {D 110}

   f {D 110; P 135:0}
   l {D 110; P 135:0}
   EH {D 110; P 135:0}
   ks {D 220; P 135:0}
   UW {D 110; P 135:0}
   OW {D 220; P 135:0}
   s {D 110; P 180:0}
   AA {D 220; P 180:0}
   r {D 110; P 135:0}
   UW {D 110; P 135:0}
   m {D 110; P 135:0}
   ~ {D 110; P 135:0}
   % {D 110}
[[inpt TEXT]]

結果

$ say < tune.txt
→ http://www1419ue.sakura.ne.jp/tune.mp3

終わりに

12/25までまだまだ枠に空きがあるので、多分また何か書きます!

naoya_t
自然言語処理とか機械学習とか競技プログラミングとか
https://naoyat.hatenablog.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away