テキスト読み上げ AquesTalk pico LSI
2020.05.19 / 2024.05.12 I2C通信追加
YouTubeでポイントを説明しています。画像をクリックすると再生できます。
テキストの音声読上げの第2弾です。
前回は、MITライセンスの gTTS (Google Text to Speech)を利用して、ソフトウェアにより音声合成を行い、テキストを読み上げました。
今回はAquesTalk音声合成LSIを用いて、日本語テキストを読み上げてみたいと思います。

音声合成エンジンAquesTalkは、組み込み用に開発された小型軽量のエンジンで、テキスト情報をリアルタイムに音声に変換して出力します。
AquesTalkには4種類ののエンジンがあります。
→規則音声合成エンジン AquesTalkシリーズ
■AquesTalkシリーズ
AquesTalk1 (旧AquesTalk)
声の種類は1つに固定されていて基本は女声ですが、別途8種類の中から選択もできます。16bit CPUから動作します。
AquesTalk2
声の種類を規定する16KB程度のデータを差し換えることで、動的に14種の中から声種を切り替えられる特長を持っています。
AquesTalk10
32bitシステムへの組み込みに最適な最新の音声合成エンジンです。
AquesTalk,AquesTalk2の後継として、両エンジンの特徴を維持したまま、クリアな声質、高い明瞭性、パラメータで声質を調整可能などの特徴を持っています。
AquesTalk pico
シリーズ中、最小サイズのエンジンです。RAM500byte、ROM30Kbyte、8bit CPUという比類ない極小リソースでリアルタイムの音声合成ができます。リソース制約の厳しい小型の組み込み機器に適しています。 このエンジンを1チップマイコンに組み込んだ音声合成LSI AquesTalk pico LSI も販売しています。
■製品
AquesTalk Pico LSI
AquesTalk picoエンジンを組み込んだ1チップの音声合成LSIです。
AquesTalk ESP32
Espressif Systems製のマイクロコントローラ ESP32用の音声合成ライブラリです。
AqKanji2Koe-MとAquesTalk picoエンジンが移植されており、漢字を含むテキストからの音声合成ができます。
AquesTalk Pi
Raspberry Pi 上で音声合成を可能にするアプリケーションプログラムです。
AqKanji2Koe-AとAquesTalk(1)エンジンが使われており、少ない処理量で高速に音声合成できます。
AquesTalk TTS
Android TTS API準拠のテキスト音声合成エンジン アプリです(ライブラリではありません)。
AqKanji2Koe-AとAquesTalk(1)エンジンが使用されています。
AquesTalk10エンジンを採用し、機能も拡張した 「AquesTalk TTS Pro」もあります。
今回使用したのは、AquesTalk Pico LSI で、かな表記の音声記号列を音声に変換する音声合成LSIです。
この音声記号列は、簡単にいうと、ローマ字表記のASCIIテキストを、アクセント記号、句切記号、タグ記号で装飾したものです。
Atmel社(Microchip社)の8bitマイクロコントローラ ATmega328Pに、音声合成ミドルウェアAquesTalk pio をファームウェアとして搭載した製品です。
・ATP3011F1-PU:ゆっくりな女性の音声
・ATP3012R5-PU:小型ロボットの音声
の2つを秋月電子通商さんで購入しました。
■配線
ベースがATMega328 なので、Arduino uno の使用方法と違いはなく、必要なピンのみを引き出します。
・1番のリセットピンはLOWでリセットが掛かるので、3.3Vに繋いでHIGHにします。※資料によるPULL-UPを有効にしてあり、この結線は不要と思われます
・2,3番ピンはUART通信用です。ラズパイの8,10番ピンと接続します。
・7番ピンは電源へ、8番ピンはGNDに接続します。
・9,10番ピンは、16MHz発振器に接続して、コンデンサを介して、GNDに落とし込みます。
・11番ピンは、動作クロックの指定で、HIGHにすると16MHz、LOWで10MHzで動作します。※資料によるPULL-UPを有効にしてあり、この結線は不要と思われます
詳細は音声合成LSI「AquesTalk pico LSI」ATP301Xのデータシートを参照してください。

また、ATP3012シリーズとATP3011シリーズでは若干の違いがあります。
ATP3011では、内部クロックを使用しているので、外部に発振器を取り付ける必要はありません。
音声出力用で使用するピンも異なります。

データシートにある外部スピーカーの配線図です。

ブレッドボード上に配線すると、こんな感じになります。

ATP3012で使用した電子部品
水晶発振器(16MHz)
セラミックコンデンサ 22pF(22)×2
抵抗10KΩ×2
基板取付用スピーカーユニット 8Ω0.08W 700~4kHz
抵抗5.1KΩ
トランジスタ 2SC1815
ユニバーサルプリント基板×2
補足:Arduinoボードを利用した簡易動作
ATP3012/ATP3011のベースチップは、Arduino unoと互換性があるので、Arduino uno に実装されている
ATmega328(P)をATP3012に差し替えることで、簡単に評価、動作を確認することもできるようです。
■日本語文字をローマ字に変換する
AquesTalkの音声合成エンジンは、漢字を含むテキストを、かな表記の音声記号列に変換する言語処理部 AqKanji2Koeと、
音声記号列を音声に変換する規則音声合成部 AquesTalkの2つのモジュールに分かれています。

言語処理ライブラリAqKanji2Koeを使用するにはライセンス購入が必要になりますので、
今回はこの言語処理ライブラリは使わずに、漢字をローマ字に変換できるPythonライブラリ "pykakasi" を使ってみました。
pykakasiモジュールのインストール
$ sudo pip3 install git+https://github.com/miurahr/pykakasi
pythonを起動して、kakasiの機能を確認していきます。
$ python3
>>> from pykakasi import kakasi
>>> kakasi = kakasi()
>>> kakasi.setMode('H', 'a')
>>> kakasi.setMode('K', 'a')
>>> kakasi.setMode('J', 'a')
>>> conv = kakasi.getConverter()
ライブラリーをインポートします。setMode では、カタカナ、ひらがな、漢字をローマ字に変換するよう指示しています。
setModeオプション指定
| Option | Description | Values | Note |
| K | Katakana conversion | a,H,None | roman, Hiragana or non conversion |
| H | Hiragana conversion | a,K,None | roman, Katakana or non conversion |
| J | Kanji conversion | a,H,K,None | roman or Hiragana, Katakana or noconv |
| a | Roman conversion | E,None | JIS ROMAN or non conversion |
| E | JIS ROMAN conversion | a,None | ascii roman or non conversion |
次にどう変換されるか確認しておきます。
>>> text='きょうの天気は、曇り時々晴れです'
>>> print(conv.do(text))
kyounotenkiha、kumoritokidokiharedesu
日常的な文章はかなり正確に変換されるようです。
ただ、AquesTalkでは「は」を「わ」として発音したい場合は、ローマ字よみを「wa」とする必要があります。
特殊記号を変換してみます。
>>> text = '?!~ー()“”「」・、。..'
>>> print(conv.do(text))
?!~-()“”「」.、。..
音を延ばす記号と、中ドット以外は、そのまま出力されています。
おそらく、kakasiの辞書に登録されていない漢字はそのまま出力するのでしょう。
固有名詞を変換してみます。
>>> text='どうも霊夢です。魔理沙です'
>>> print(conv.do(text))
doumoreiyumedesu。marisadesu
固有名詞も、kakasiで変換する前に、独自に変換する必要があります。
なぜ、「魔理沙」が正確に変換されたかというと、kakasiの内部で単語が「魔」と「理沙」に分解されて、変換されたからです。
母音がダブる場合
>>> text = '大きい'
>>> print(conv.do(text))
ookii
「oo」→「o-」、「ii」→「i-」にして、母音を延ばすようにしたほうが、聞きやすいかもしれません。
■AquesTalk音声記号列仕様(抜粋)
| ' | アクセント |
| . | 文の終わり |
| ? | 文の終わり、文末の声が高めになる |
| (半角空白) | 無音区間がはいる。 文中の息継ぎ部分に指定する。一般に次の音が高くなる。 |
| , | 半角空白より短いボーズ |
kakasiで変換する前に実施する置換処理
霊夢→reimu、は、→wa,、?→?、~→kara など
kakasiでの変換後に追加する置換処理
uu→u-、oo→o-、ee→e-、aa→a-、ii→i-、iu→yu- など
■日本語→ローマ字変換処理
Pythonコードの抜粋です。辞書の部分は用途に応じて変更してください。
DICT_BEFORE = {'霊夢':'reimu','は、':'wa,',
'?':'?','!':'\'.','~':'kara','、':',','。':'.'}
DICT_AFTER = {'uu':'u-','oo':'o-','ee':'e-',
'aa':'a-','ii':'i-','iu':'yu-','ha,':'wa,'}
def kanji2roman(self, msg):
for target, dest in self.DICT_BEFORE.items():
msg = msg.replace(target,dest)
msg = self.cnv.do(msg)
for target, dest in self.DICT_AFTER.items():
msg = msg.replace(target,dest)
return msg;
■AquesTalk pico LSIとのUART通信
ローマ字テキストの終端にCR(0x0D)を付加して、送信します。
LSIが発音中に、追加のテキストを送信すると、BUSY(*)が返されます。
READY(>)になるのを確認してから、次のテキストを送信します。

UART通信制御用のコードの抜粋は下記のようになります。
def write(self, msg):
self.msg = self.kanji2roman(msg) + "\r"
while True:
self.ser.write(bytes("\r",'ascii'))
rx = self.ser.read()
status = rx.decode('utf-8')
if status=='*': # busy
sleep(1)
elif status=='>': # ready
self.ser.write(bytes(self.msg,'ascii'))
rx = self.ser.read()
break
ATP3012での転送速度(ボーレート)はデフォルトで9600bpsです。
ATP3011でのUART通信では、ボーレート自動設定のため、最初に'?'を送信する必要があります。

if model == 'ATP3011':
self.ser.write(bytes('?','ascii'))
rx = self.ser.read()
動作が確認できましたら、ブレッドボードからユニバーサルプリント基板へ移し込みます。
LSIは交換可能なように、丸ピンICソケット上に挿しています。

スピーカー部分を分離して作成しています。回路上の抵抗は変更可能なように、丸ピンICソケット上に挿しています。

Raspberry Pi Zero WH とつなぐと、こんな感じになります。

実際の使い方としては、動的に日本語をAquesTalkに合った、かな表記の音声記号列に換えるのではなく、
定型文章的な用途においてあからじめ適切な音声記号列に編集しておいて、音声合成させるほうがよいと思います。
■サンプルソースコード
from serial import Serial
from time import sleep
from pykakasi import kakasi
import time
import sys
class text2speech(object):
SERIALPORT = '/dev/ttyAMA0'
DEVICE = 'ATP3012'
TIMEOUT = 3
BAUDRATE = 9600
DICT_BEFORE = {'霊夢':'reimu','は、':'wa,','?':'?','!':'\'.','~':'kara',
'(':',',')':',','「':',','」':',','、':',','':'','。':'.','.':'.',}
DICT_AFTER = {'uu':'u-','oo':'o-','ou':'o-','ee':'e-','aa':'a-','ii':'i-','iu':'yu-','ha,':'wa,'}
def __init__(self, model='ATP3012'):
self.model=model
self.ser = Serial(self.SERIALPORT, baudrate=self.BAUDRATE, timeout=self.TIMEOUT)
self.kks = kakasi()
self.kks.setMode('H', 'a')
self.kks.setMode('K', 'a')
self.kks.setMode('J', 'a')
self.cnv = self.kks.getConverter()
if model == 'ATP3011':
self.ser.write(bytes('?','ascii'))
rx = self.ser.read()
def kanji2roman(self, msg):
for target, dest in self.DICT_BEFORE.items():
msg = msg.replace(target,dest)
msg = self.cnv.do(msg)
for target, dest in self.DICT_AFTER.items():
msg = msg.replace(target,dest)
return msg;
def write(self, msg):
#self.msg = self.kanji2roman(msg) + "\r"
self.msg = msg
while True:
self.ser.write(bytes("\r",'ascii'))
rx = self.ser.read()
status = rx.decode('utf-8') # status is null
if status=='*': # busy
sleep(1)
elif status=='>': # ready
self.ser.write(bytes(self.msg,'ascii'))
rx = self.ser.read()
break
if __name__ == '__main__':
import sys, os
if len(sys.argv) == 2:
model = sys.argv[1]
else:
model = text2speech.DEVICE
if not os.path.exists(text2speech.SERIALPORT):
sys.exit("ERROR: Serial port not found at: %s" % text2speech.SERIALPORT)
print ("Testing AquesTalk Pico LSI: %s" % model)
ts = text2speech(model=model)
text='きょうの天気は、曇り時々晴れです'
ts.write(text)
ATP3011はLSIと抵抗1本で済んでしまうため、スピーカーと一体型にしてしまいました。

■I2C通信モードへの変更 2024.05.12
AquesTalk pico LSI は、UART、I2C、SPI通信の3つのモードをサポートしています。

TeraTermでローマ字入力を行い、ESP32にTELNET送信し、I2C(Qwiic)接続でAquesTalk Picoにデータを受け渡し、音声合成を行います。
ATP3012シリーズ

・4番ピン(SMOD0)をLOWに落とすことでI2C通線モードになります。
・27番(SDA)、28番(SCL)にプルアップ抵抗を接続しています。
・ATP3012の動作クロック16MHz用に発振子を取り付けています。


ATP3011シリーズ

・ATP3011は内蔵クロック8MHzで動作しています。


簡易D級アンプ・スピーカー


ESP32汎用機


【参考文献】
・日本語文字をローマ字に変換する
・Pykakasiで文章をひらがなへのバラバラ変換して遊んでみた♪
・PYKAKASI documentation
・自作Arduino互換回路(ブレッドボード版)
|
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」
「一念発起して何かを始めても、いつも三日坊主で終わってしまう」
「色んなことを先延ばしにしたまま、時間だけが過ぎていく」
そこで本書では、そんな著者が独自に開発した、
まったく新しい目標達成メソッド「100日デザイン」について、
その知識と技術を、余すところなくご紹介します。
まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。
ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。
今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。
ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。
29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!
【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。
基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。
Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説!
500以上のサンプルを掲載。実行結果も確認。
全24章の包括的なチュートリアル。
ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS…
全WEB媒体で効果バツグン!
カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術
小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。
Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード
電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)
|