初めに
先日以下のようなライブラリを発表しました
【新作OSSを一挙3本公開!🎉】
— ようさん (@ayousanz) 2025年9月4日
音声合成・Unity・デスクトップアプリの領域で、3つのオープンソースプロジェクトを公開しました!
🚀piper-plus: 高速・軽量な日本語TTSエンジン
🎮uPiper: Unityでキャラクターを喋らせるプラグイン
🤖uDesktopMascot: 音声で対話できるマスコットアプリ pic.twitter.com/7AftxuVu5O
これを実際に動かしてみます (日本語の発音が怪しいのは、バグ + 学習不足なので後日改善される予定です)
以下がpiper-plusのリポジトリです
開発環境
- Windows 11
- uv
環境構築
まずはuvで環境構築を行います
uv venv -p 3.12 .\.venv\Scripts\activate
次に必要なライブラリをインストールします
uv pip install piper-tts-plus==1.5.5 pyopenjtalk-plus
コードから推論を実行
以下のコードを実行して日本語と英語を生成します
#!/usr/bin/env python # -*- coding: utf-8 -*- """ piper-tts-plus 1.5.5 テストスクリプト 日本語と英語の音声合成 """ import sys import os import wave from pathlib import Path # UTF-8エンコーディングを強制 os.environ['PYTHONIOENCODING'] = 'utf-8' if sys.platform == "win32": sys.stdout.reconfigure(encoding='utf-8') sys.stderr.reconfigure(encoding='utf-8') from piper import PiperVoice def main(): print("=== piper-tts-plus 1.5.5 音声合成テスト ===\n") # モデルパス base_path = Path(__file__).parent.parent ja_model = base_path / "test" / "models" / "ja_JP-test-medium.onnx" ja_config = base_path / "test" / "models" / "ja_JP-test-medium.onnx.json" en_model = base_path / "test" / "models" / "test_voice.onnx" en_config = base_path / "test" / "models" / "test_voice.onnx.json" # 日本語音声生成(prosody=Falseを強制) print("1. 日本語音声を生成中...") if ja_model.exists() and ja_config.exists(): voice_ja = PiperVoice.load(str(ja_model), config_path=str(ja_config), use_cuda=False) # phonemizeメソッドをオーバーライドしてpyopenjtalk.g2p()を直接使用 import pyopenjtalk from piper.phonemize.token_mapper import map_sequence original_phonemize = voice_ja.phonemize def custom_phonemize(text): """Use pyopenjtalk.g2p() with proper token mapping""" phoneme_str = pyopenjtalk.g2p(text) tokens = phoneme_str.split() # pauseを"_"に変換 tokens = ["_" if t == "pau" else t for t in tokens] phonemes = ["^"] + tokens + ["$"] # 重要: map_sequenceでマルチ文字音素をPUA文字に変換 return [map_sequence(phonemes)] voice_ja.phonemize = custom_phonemize japanese_text = "こんにちは、これはバージョン1.5.5のテストです" output_ja = "japanese_v155.wav" with wave.open(output_ja, "wb") as wav_file: voice_ja.synthesize(japanese_text, wav_file) # phonemizeメソッドを元に戻す voice_ja.phonemize = original_phonemize print(f" ✓ 生成完了: {output_ja}") print(f" テキスト: {japanese_text}") else: print(" ✗ 日本語モデルが見つかりません") # 英語音声生成 print("\n2. 英語音声を生成中...") if en_model.exists() and en_config.exists(): voice_en = PiperVoice.load(str(en_model), config_path=str(en_config), use_cuda=False) english_text = "Hello, this is a test with version 1.5.5" output_en = "english_v155.wav" with wave.open(output_en, "wb") as wav_file: voice_en.synthesize(english_text, wav_file) print(f" ✓ 生成完了: {output_en}") print(f" テキスト: {english_text}") else: print(" ✗ 英語モデルが見つかりません") print("\n=== 生成完了 ===") print("\n生成されたファイル:") for file in ["japanese_v155.wav", "english_v155.wav"]: if os.path.exists(file): size = os.path.getsize(file) print(f" • {file} ({size:,} bytes)") if sys.platform == "win32": print("\n再生するには:") print(" start japanese_v155.wav") print(" start english_v155.wav") return 0 if __name__ == "__main__": try: sys.exit(main()) except Exception as e: print(f"\nエラー: {e}") import traceback traceback.print_exc() sys.exit(1)
これを実行すると以下のようなログが表示されます
python test_v155.py === piper-tts-plus 1.5.5 音声合成テスト === 1. 日本語音声を生成中... ✓ 生成完了: japanese_v155.wav テキスト: こんにちは、これはバージョン1.5.5のテストです 2. 英語音声を生成中... eSpeak-NG not found Missing phoneme from id map: H Missing phoneme from id map: 1 Missing phoneme from id map: 5 Missing phoneme from id map: 5 ✓ 生成完了: english_v155.wav テキスト: Hello, this is a test with version 1.5.5 === 生成完了 === 生成されたファイル: • japanese_v155.wav (177,708 bytes) • english_v155.wav (61,484 bytes) 再生するには: start japanese_v155.wav start english_v155.wav
これを実行することで以下のファイルが生成されます
