Pythonで音声合成してみた(Google Cloud Text-to-Speech API)

スポンサーリンク

GCP音声合成APIがあることを知識としては知っているけど、使ったことがなかったので使ってみました。 ネットで見かけるサンプルはmp3ファイルに保存する例が多いけど、自分が使いたい用途はファイルに保存せずに再生だったので修正。

動作確認環境

Windows 11 バージョン22H2 (OSビルド 22621.1105)
ネットワーク:WiFi
python 3.10

処理時間

上記環境と下記プログラムで音声合成の処理時間は0.65秒~0.7秒ぐらい。

プログラム

必要に応じてpythonパッケージをインストール

pip install --upgrade google-cloud-texttospeech pyaudio

GCPの認証関連の設定をした上で、次のプログラムを実行

プログラム

from google.cloud import texttospeech
import pyaudio
import wave
import io


def tts(text: str, format_name: texttospeech.AudioEncoding) -> bytes:
    print('tts setup')
    client = texttospeech.TextToSpeechClient()
    synthesis_input = texttospeech.SynthesisInput(text=text)

    voice = texttospeech.VoiceSelectionParams(
        name='ja-JP-Neural2-B',
        language_code="ja-JP",
        ssml_gender=texttospeech.SsmlVoiceGender.SSML_VOICE_GENDER_UNSPECIFIED
    )

    audio_config = texttospeech.AudioConfig(
        audio_encoding=format_name,
        # 読み上げ速度 (0.25~4.0)
        speaking_rate=1.25,
        # ピッチ (-20.0~20.0)
        pitch=0,
        # ゲイン (-96.0~16.0)。-6で半分。6で2倍。10以下を推奨
        volume_gain_db=0.0,
        # 他にもオプションあり
    )

    print('tts synthesize_speech')
    start = time.perf_counter()
    response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
    print(time.perf_counter() - start)
    return response.audio_content


def tts_save_mp3(filename: str, text: str) -> None:
    audio_content = tts(text, texttospeech.AudioEncoding.MP3)
    print('save mp3')
    with open(filename, "wb") as out:
        out.write(audio_content)


def tts_save_wav(filename: str, text: str) -> None:
    audio_content = tts(text, texttospeech.AudioEncoding.LINEAR16)
    print('save wav')
    with open(filename, "wb") as out:
        out.write(audio_content)


def tts_play(text: str) -> None:
    audio_content = tts(text, texttospeech.AudioEncoding.LINEAR16)
    print('play')
    wav_play(audio_content)


def wav_play(audio_content: bytes) -> None:
    wf = wave.open(io.BytesIO(audio_content), 'rb')

    pa = pyaudio.PyAudio()
    stream = pa.open(
        format=pyaudio.get_format_from_width(wf.getsampwidth()),
        channels=wf.getnchannels(),
        rate=wf.getframerate(),
        output=True
    )

    chunk_size = 1024
    data = wf.readframes(chunk_size)
    while len(data) > 0:
        stream.write(data)
        data = wf.readframes(chunk_size)

    stream.stop_stream()
    stream.close()

    pa.terminate()


if __name__ == "__main__":
    tts_save_mp3('output.mp3', '音声合成結果をmp3ファイルとして出力しました')
    tts_save_wav('output.wav', '音声合成結果をwavファイルとして出力しました')
    tts_play('音声合成結果を再生しています')


リンクやメモ

公式ドキュメント
お試しページ

WaveNet 音声、Neural2 音声の料金
1 文字あたり $0.000016 米ドル
100万文字あたり、$16.00 米ドル
無料枠100万文字/月

利用できるモデル

日本語だとWaveNetNeural2の合計7種類

音声タイプ 言語コード 音声名 SSML の性別
Neural2 ja-JP ja-JP-Neural2-B 女性
Neural2 ja-JP ja-JP-Neural2-C 男性
Neural2 ja-JP ja-JP-Neural2-D 男性
WaveNet ja-JP ja-JP-Wavenet-A 女性
WaveNet ja-JP ja-JP-Wavenet-B 女性
WaveNet ja-JP ja-JP-Wavenet-C 男性
WaveNet ja-JP ja-JP-Wavenet-D 男性

制限事項
1リクエストあたりの合計バイトには制限があり、5,000まで。

リリースノート

公式Pythonクライアントライブラリのソースコード
公式Pythonクライアントライブラリのドキュメント

・ベータ版だけど、Custom Voiceが提供されている。ただし、利用するには問い合わせ必要。