AquesTalkをPythonから動かす①まずは動かす

Programming

僕が開発をしたプログラミングロボットQumcumの小学生にもわかりやすいYoutube動画コンテンツを作るために、ナレーションに使う音声合成のアプリやエンジンをさがしていた。
けど…ふっと気が付くと….QumcumにはAqueTalk使ってたじゃないか!そうか、Qumcumに使っているQumcumの声でしゃべらせればいいんだ!と気づいた。
どうしてこんなことに気づかなかったのだろう…ということで早速AquesTalkのHPにたどり着きWindowsで使用できるQumcumの声をもつエンジンを探してみた。

試してみる

まずは、Windows版でもQumcumの声が出るのかを知りたい。そこでオンラインデモのページに行き、まずはいろいろしゃべらせてみたが、まともにQumcumの声であることが確認できた。
ここのページの秀悦なことに、自分でしゃべらせたい文字を入れると、アクセント記号を含んだおしゃべり文字を生成してくれる。そして、それがなんと、文字と言葉をみて、かなり正確なアクセント記号を付加してくれるのである。例えば下記…

言語処理部分に文字を入れてConvertボタンをクリックすると、規則音声合成部分にアクセント記号付きのカナ文字を出力してくれる。そしてこれをPlayさせれば指定の声とスピードでしゃべってくれる。しゃべらせてみた結果がこれです。

▼「僕はクムクム、未来ロボットなんだ!」

アクセントがちょっと違うのでアクセント記号を少し入れて調整してみる。

▼「ボ’クワ/ク’ムクム、ミライロ’ボットナ/ンダ/」

いずれにしても使えそうで声もいろいろ変えられそうなので、Youtubeで2人で会話をさせる音声として使えそうだ!いったん実験的に台本を作って、音声を変えながら録音してみようと作ってみたのが下記…アクセントは一つ一つ作るのが面倒なので、とりあえずいじらずにしのまま吐き出してみる。そして、テンポよく切れ間なく聞こえるようにアプリで隙間をカットしてみた。

台本—-
(クムクム)やぁ!みんなこんにちわ!僕はクムクム。
3020年から、タイムポッドに乗ってやってきた、お腹ポッコリおしゃべりロボット。
未来世界の先生から、みんなにいろいろ伝えるように命令されてやってきたんだ!
いま、みんなのまわりで起こっていること、これから起こること
いっぱいおしえるね!
いっしょにスリスリもつれてきたんだ!
(スリスリ)やっほいほいみぃ~なさん、わっちはスリスリのん!
なんかよ~しらんけどぉ~…いろいろおしえろっちゅうのん!よ~しらんけどぉ…
(クムクム)もう…スリスリはすぐにそうなんだから…
とにかく、すりすりも一緒に、みんなよろしくね!
(スリスリ)よろしくのん!なんかしらんけどぉ

考察開始

それなりに使えるけど、できればアクセントはパターン化して覚えさせておいて、会話は勝手に台本から二人が切り替わってしゃべって、そのままWAVで落ちてくれると実に助かる。毎回毎回台本を切り刻んでは音声に変えて録音してそれをつなぎ合わせていたのでは作業が厄介!

●できて欲しいこと

  1. おしゃべりする人を区別した台本ををそのまま読み込む
  2. 単語のアクセントはパターン化してそれを自動で使う
  3. そのままWAVで落ちる
  4. あとの編集用にできたらおしゃべりする人をLとRにわける

こんなことを考えたら、結局自分でプログラムを組むしかないと気づき….はぁ…いつもの悪い癖…プログラミングの趣味にはまっていく。結局完成品を作る前のこの開発作業がお好きだから…まぁ仕方ないか性分だから…

確認をして方針を決める

プログラムでAquesTalkを使うには、どうもAquesTalkライセンスを購入する必要がある。そこでライセンスがいくらなのか調べてみるとオンラインストアを見るとなんと6380円で購入できる。自分の自由なアプリを開発できてこの値段はお得である。しかも購入前にすべてダウンロードできてお試しができるから早速ダウンロードをしようとするが・・・・いろいろ種類があってどれがいいのかよくわからない。PicoやESP32はすでに使用しているのでわかるけど、Win用がいくつか用意されているのでよくわからない。… どうも調べていくとというか、タイトルをクリックするとその製品の詳細が書いてあったので、結局、10を選ぶと最新ですべてが包括されているようなのでこれをダウンロードしてみることにした。

実験(Pythonで動かすまで)

ファイルはZipのプログラムとPDFのドキュメントで提供されていて、基本はC言語で書かれている。Cで書かれているのであれば、まあなんとでもなるだろう!ちょっと前までは.NETで開発を始めたのだけど、最近はPythonが便利なので、とりあえずPythonで動かすことを前提に進めていく。

ChatGPTに聞く

最近は実にぐうたらで、ほとんど自分で考えないしググらない!すべてこいつに聞いて解決をしていく。もちろん結構嘘もできないこともあるけれど、それは自分の経験でカバーしていけばいいので、とにかく便利である。

Pythonで動かす基本を聞く

まずは、プログラムのZipファイルをそのままぶち込むか、フォルダー構成をマークダウンし、合わせてPDFドキュメントをぶち込んでいきなり聞く。ChatGPTにはまずはこれが一番!うだうだ考えてないでまずは聞く。ChatGPTは秘密漏洩するとかいってるけど、基本はしないと書いてある。けど私は怖いので、できるだけ聞きたいことを要約して、ファイル名を変えたり文字を変えたりして聞く。また危ないところは外す。

今回もマニュアルの抜粋や書き直しをして、ファイルは構成を書いて以下のようにぶち込んだ。ファイル名などは元の通りに合わせたある。

ChatGPTの答え….

とりあえず完璧なような答えが出てきた。が安心はしない!結構間違えがあるから…

ChatGPTのサンプルを動かしてみる

とりあえず70%期待30%あきらめて、チャットGPTで出力された3つのPythonコードをVSCodeに張り付けてまずは動かしてみる。まずは検証なんかしない!とにかく動かして、その結果をChatGPTに報告する。


import ctypes
from ctypes import c_char_p, c_int, c_ubyte, POINTER, Structure

# DLL読み込み(適宜パスを変更)
aqtk = ctypes.CDLL(r"./AquesTalk.dll")

# AQTK_VOICE 構造体の定義
class AQTK_VOICE(Structure):
    _fields_ = [
        ("bas", c_int),
        ("spd", c_int),
        ("vol", c_int),
        ("pit", c_int),
        ("acc", c_int),
        ("lmd", c_int),
        ("fsc", c_int)
    ]

# 関数の戻り値と引数の型定義
aqtk.AquesTalk_Synthe_Utf8.restype = POINTER(c_ubyte)
aqtk.AquesTalk_Synthe_Utf8.argtypes = [POINTER(AQTK_VOICE), c_char_p, POINTER(c_int)]
aqtk.AquesTalk_FreeWave.argtypes = [POINTER(c_ubyte)]
def synthesize_to_wav(text_utf8, output_path="output.wav"):
    voice = AQTK_VOICE(bas=0, spd=120, vol=100, pit=100, acc=100, lmd=100, fsc=100)  # gVoice_F1相当
    size = c_int(0)

    # UTF-8で合成
    wav_ptr = aqtk.AquesTalk_Synthe_Utf8(ctypes.byref(voice), text_utf8.encode('utf-8'), ctypes.byref(size))
    if not wav_ptr:
        print(f"音声合成エラー: コード={size.value}")
        return False

    # 書き出し
    with open(output_path, "wb") as f:
        f.write(ctypes.string_at(wav_ptr, size.value))

    aqtk.AquesTalk_FreeWave(wav_ptr)
    print(f"WAVファイル生成完了: {output_path}")
    return True
synthesize_to_wav("コンニチワ。")

結果

よ~わからんというか考える気がない!これがGPTプログラミングの悪いところ。とにかくこのエラーをポンとGPTに張り付けてやると…

ということで、あ!そかそか!ということでコードの書き換えを行う。
こまごまと修正方法を教えてくれるが、それはおおきなお世話なのでちゃっちゃとDLLを読んできるところを書き直すかDLL同じフォルダーにぶち込む。気を付けるのは32と64ビットの違い。私のOSは64なので….今更32いるかなぁ…とにかく64のDLLを同一フォルダーにぶち込んだ。

その結果
ちょっとは考えろよ!と自分に思うが、考えない。とにかく出た結果でまずは動くまで根性でGPTと遊んでみる。

答え


とにかく考えるのがめんどくさいけどそろそろ真面目に読んで対処してみる。
結局DLLの場所が悪いだけなので

aqtk = ctypes.CDLL(r“C:\Users\yoshikawa\Desktop\クムクム小学生\Python\AquesTalk.dll”)
と書き直して実行をしてみる。

おおお?なんかできたか?
ちっよつついてみるかと出来上がったであろう putput.wavを探してみるがどこにも見当たらないので、これまたGPTに聞く
どうもどこなんだかわからないので、こんな投げかけをして答えを出してもらった!

だったら最初から俺の気持ち読んでこうしてくれよ!と思う

import ctypes
from ctypes import *
import os

# DLLのパス(あなたの環境に合わせて修正)
aqtk = ctypes.CDLL(r"C:\Users\yoshikawa\Desktop\クムクム小学生\Python\AquesTalk.dll")

# AQTK_VOICE構造体定義
class AQTK_VOICE(Structure):
    _fields_ = [
        ("bas", c_int),
        ("spd", c_int),
        ("vol", c_int),
        ("pit", c_int),
        ("acc", c_int),
        ("lmd", c_int),
        ("fsc", c_int)
    ]

# DLL関数の型設定
aqtk.AquesTalk_Synthe_Utf8.restype = POINTER(c_ubyte)
aqtk.AquesTalk_Synthe_Utf8.argtypes = [POINTER(AQTK_VOICE), c_char_p, POINTER(c_int)]
aqtk.AquesTalk_FreeWave.argtypes = [POINTER(c_ubyte)]

# 音声合成関数(パス指定可能)
def synthesize_to_wav(text_utf8: str, wav_path: str):
    # 声質設定(F1相当、話速少し速め)
    voice = AQTK_VOICE(bas=0, spd=120, vol=100, pit=100, acc=100, lmd=100, fsc=100)

    size = c_int(0)
    wav_ptr = aqtk.AquesTalk_Synthe_Utf8(byref(voice), text_utf8.encode('utf-8'), byref(size))
    if not wav_ptr:
        print(f"音声合成エラー: コード={size.value}")
        return False

    # 指定されたパスにWAVファイルを保存
    with open(wav_path, "wb") as f:
        f.write(string_at(wav_ptr, size.value))

    aqtk.AquesTalk_FreeWave(wav_ptr)
    print(f"音声合成成功: {wav_path}")   
    return True

output_path = r"C:\Users\yoshikawa\Desktop\konnichiwa.wav"
synthesize_to_wav("コンニチワ。", output_path)

期待通りしゃべるか?

おおおおお~ちゃんと喋るではないか!
ここで、こんにちわ の に が ぬ になっているのは、これはデモ版だからしょうがない!これは正式版を購入すればなおるので…! いける!基礎実験は終わった!あとは作るだけである。

最後に

この記事のアイキャッチ画像をついでなのでGPTに作ってもらうことにする。

音声合成AquesTalkをチャットGPTとPythonでプログラミング というタイトルで、かわいいブログ用のアイキャッチ画像を作ってください。サイズは16:9です。

さて、どんなのがでるかな….アイキャッチに貼っておきます!
ださいだろうなぁ…日本語ちゃんと出るかなぁ….

コメント

タイトルとURLをコピーしました