【M5Stack】ATOM Echo で AquesTalk ESP32 スモール辞書版 (2MB) をコードに埋め込んで超高速で使う
【AIスタックチャン ミニマル をAquesTalk(ESP32内部プログラム)でしゃべらせたい】
AquesTalk ESP32 スモール辞書版 (2MB)が公開されました!
AIスタックチャンは、外部機能(Web版 VOICEVOX等)に作成してもらった音声ファイルを再生していますが、この外部サービス抜きでESP32自身の処理でしゃべらせたい。
しかしミニマルは、M5Stack(ESP32)シリーズの中でもさらに小さいAtom Echoを使用しており、そのFlashメモリも4MBと超小型(泣 😢 が、この機会に外部機能抜きでしゃべらせたいので、まずは"シンプルな Atom EchoでAquesTalk ESP32 スモール辞書版 (2MB)再生環境"を作ってみました。
【超高速 & SDカード不要のAquesTalk!】
記事によると最速2.92msの超高速再生のようですが、私がAtom EchoをArduino環境で構築した際の最速は3.13msと、確かに超高速でした!何よりSDカードが付いていないAtomにシンプルに使えるのが素晴らしい!😋
起動後、ボタンAを押すと、音声の発声とともに、画面に処理時間が表示されます(写真左)。
ちょっと驚きの2.92msでした。SDカードから読み込む場合は860msかかっていましたので(写真右)、300倍の速さです。高速といわれるSdFatライブラリを使ったときは約200msでしたので、それと比較しても70倍の速さです。
どんな感じ?
動画はAtom Echoのスピーカーを労わるため小さい音量にしていますので、再生音量を上げるとおしゃべりが聞こえます。
※Atom Echoはスピーカが弱い子なので大きい音量は出せません【作り方(PlatformIO環境)】
Arduino IDE※での作り方は、下記リンクサイトに説明がありましたが、PlatformIO環境での説明が無いため、私が試したことをこの記事にしています。
環境設定
1. PlatformIOの環境を用意した後、New Project を作成します。
まだPlatformIO環境が出来ていない人は、下記のリンクを参考ください。
2. マイコンボードと保存場所を設定します。
Board: M5Stack-ATOM , Framework: Arduino と保存場所が正しく設定されていることを確認し、Finishで開始です。
3. コンパイル環境(platformio.ini)を下記のように書き換えます。
[env:m5stack-atom]
platform = espressif32@6.2.0
board = m5stack-atom
framework = arduino
board_build.partitions = max_app_4MB.csv
upload_speed = 1500000
monitor_speed = 115200
lib_deps =
m5stack/M5Unified @ 0.1.17
build_flags=
-Llib/aquestalk-esp32_s/src/esp32/ ; Atom Echo/lite :esp32
-laquestalk_s
; Set com port if you need
; upload_port = COM11
4. ESP32パーテーション(Flash領域)設定ファイル:max_app_4MB.csv※を下記リンクからDLしてplatformio.iniと同じフォルダに置きます
Lang-shipさんの記事が分かりやすいです。
AquesTalk ESP32の取得とPlatformIO環境へコピー
以下の2つのプログラムをDLします。
1. 下記リンクより「AquesTalk ESP32(Small辞書版) 」をDLし、「aquestalk-esp32_s」フォルダをPlatformIOで制作中のlibフォルダにコピーします。
※ この記事では「2.4.4 (2024/10/30)」を使用
2. 下記リンクより[M5_AquesTalk_KM_PM.zip]をDLし、"AquesTalkTTS.h", "AquesTalkTTS_M5_PM.cpp"の2ファイルを[lib\aquestalk-esp32_s\srcフォルダ]にコピーします。さらに"M5_AquesTalk_KM_PM.ino"を[srcフォルダ]にコピーします。
3. "M5_AquesTalk_KM_PM.ino"を"main.cpp"に名前を変更し、元ファイルと入れ替えます
辞書データから16進ダンプファイル作成 - BusyBoxツール利用
私はWindows環境のため、Linuxのxxdコマンドが使えないので、BusyBoxというツールを使用しました。使える方※は下記の方法で[lib\aquestalk-esp32_s\aq_dic]にコピーした”aqdic_m.bin”より作成ください。
■辞書データを16進ダンプする
辞書ファイルは、AquesTalk ESP32ライブラリの /aq_dic/aqdic_m.bin を使います。
これを、Linuxのxxdコマンドで、C言語のインクルードファイル形式にダンプします。
$ xxd -i aqdic_m.bin aqdic_m_l.h
http://blog-yama.a-quest.com/?eid=970204 より
※ WSL2のLinuxのxxdコマンドで作成できることは確認しました。が、このためだけにWSL2を入れたくない人向けの説明です。
1. BusyBoxをDLする
・この方の説明が分かりやすかったです。
2. BusyBoxのxxdコマンドで辞書データから16進ダンプファイル作成
コマンドプロンプトを開き、DLしたbusyboxと同じフォルダに移動。その後、bashオプションでlinux風コマンドを使えるようにして、下記のようにダンプファイル "aqdic_m_l.h"を作成します。
busybox64u.exe bash
$ xxd -i ./aqdic_m.bin >> ./aqdic_m_l.h
$ exit
※aqdic_m.binをbusybox64u.exeと同じフォルダに事前にコピーしておいてください
3. ダンプファイル "aqdic_m_l.h"をPlatformIO環境の[lib\aquestalk-esp32_s\srcフォルダ]にコピーし、1行目を修正して保存します。
出来上がったファイル(aqdic_m_l.h)の変数の定義を下のように修正し、スケッチ .inoと同じフォルダに配置します。
alignas(4) static constexpr uint8_t aqdic_m_bin[] = {
http://blog-yama.a-quest.com/?eid=970204 より
alignas(4) static constexpr uint8_t aqdic_m_bin[] = {
Atomへの書き込み
1. Uploadボタンで書き込んで完成!
※
おまけ:AIスタックチャンミニマル/ATOMIC Speaker Base用に編集
// !!! 辞書データをプログラムに埋め込んで使うように改変したもの
// M5_AquesTalk_KM.ino - AquesTalk ESP32 サンプルプログラム
// M5Stack用 漢字テキストからの音声合成
// ・ボタン操作で音声出力/停止
// ・シリアルモニタから任意の漢字テキスト(UTF8/CR)を送信して音声合成出力
// ・辞書データファイルはSDカードに保存しておく。
#include <Arduino.h> // Add for PlatformIO
#include <M5UnitGLASS2.h> // Add for SSD1306
// #include <M5UnitLCD.h>
// #include <M5UnitOLED.h>
#include <M5Unified.h>
#include "AquesTalkTTS.h" // AquesTalk-ESP32のラッパークラス
/// I2C接続のピン番号 // Add for SSD1306
#define I2C_SDA_PIN 21
#define I2C_SCL_PIN 25
void setup(void)
{
Serial.begin(115200);
auto cfg = M5.config();
// 試用するスピーカーに true を設定する
//cfg.external_speaker.module_display = true;
//cfg.external_speaker.module_rca = true;
//cfg.external_speaker.hat_spk = true;
//cfg.external_speaker.hat_spk2 = true;
cfg.external_speaker.atomic_spk = true;
cfg.unit_glass2.pin_sda= I2C_SDA_PIN; // Add for SSD1306
cfg.unit_glass2.pin_scl= I2C_SCL_PIN; // Add for SSD1306
M5.begin(cfg); // M5UnifiedはSD.begin()しない
M5.setPrimaryDisplayType({m5::board_t::board_M5UnitGLASS2}); // Add for M5 avatar
{ /// custom setting
auto spk_cfg = M5.Speaker.config();
/// Increasing the sample_rate will improve the sound quality instead of increasing the CPU load.
spk_cfg.sample_rate = 96000; // default:64000 (64kHz) e.g. 48000 , 50000 , 80000 , 96000 , 100000 , 128000 , 144000 , 192000 , 200000
spk_cfg.task_pinned_core = APP_CPU_NUM;
M5.Speaker.config(spk_cfg);
}
// AquesTalkの初期化
if (int iret = TTS.createK()) { // 漢字テキスト使用
if(iret==501){
Serial.print("ERR:SD card not found");
M5.Display.println("ERR:SD card not found");
}else {
Serial.print("ERR:TTS.createK()");
M5.Display.println("ERR:TTS.createK()");
}
return;
}
M5.Speaker.begin(); //Add
// M5.Speaker.setVolume(128);
M5.Speaker.setVolume(100);
// M5.Display.setTextSize(2);
M5.Display.println("AquesTalk ESP32 demo");
M5.Display.println("");
M5.Display.println("Push BtnA !");
M5.Display.println("");
// M5.Display.setTextSize(4);
}
void loop(void)
{
M5.update();
if(M5.BtnA.wasPressed()){
unsigned long ms0 = micros();
TTS.playK("新しいライブラリは、漢字テキストから音声合成ができるようになりました。", 100);
unsigned long ms = micros() - ms0;
M5.Lcd.printf("time\n %4.2f[ms] \n", ms/1000.0);
}
}
【最後に】
お疲れ様でした!こんなに作業が長いとは書いている方もビックリ!ですが、それを上回る良い使い勝手だと、ニンマリしています 😄 音声入力組合せれば、この音声合成機能が素敵に動くと信じて。
・M5社:Atom Echo / ATOMIC Speaker Base
・AquesTalk
Discussion