ストーリー
田
田中VPoE
音声認識(STT)の次は、音声合成(TTS: Text-to-Speech)だ。テキストから自然な音声を生成する技術を学ぼう
あなた
最近のTTSはかなり自然になりましたよね。社内通知の自動音声化やeラーニングのナレーション生成に使えそうです
あ
田
田中VPoE
その通り。OpenAIのTTSやElevenLabsなど、APIベースで高品質な音声が生成できるようになった。感情表現や多言語対応まで進んでいる
あなた
声のクローニングもできると聞きました。倫理面も含めて学びたいです
あ
音声合成(TTS)の概要
主要なTTSサービス
| サービス | 提供元 | 特徴 | コスト目安 |
|---|
| OpenAI TTS | OpenAI | 6種類の声、自然な抑揚 | $15/100万文字 |
| ElevenLabs | ElevenLabs | 声のクローニング、感情制御 | $5/月〜 |
| Google Cloud TTS | Google | WaveNet、多言語、SSML対応 | $4/100万文字 |
| Amazon Polly | AWS | NTTS(ニューラル)、AWS統合 | $4/100万文字 |
| Azure Speech | Microsoft | カスタムニューラル音声 | $15/100万文字 |
| VOICEVOX | OSS | 日本語特化、無料、商用利用可 | 無料 |
TTS技術の進化
第1世代: 規則合成 → 機械的で不自然
第2世代: 統計的パラメトリック → やや自然だが平坦
第3世代: ニューラルTTS → 人間に近い自然さ
第4世代: ゼロショットTTS → 数秒のサンプルで声を再現
OpenAI TTSの実装
基本的な音声生成
from openai import OpenAI
from pathlib import Path
client = OpenAI()
def text_to_speech(
text: str,
voice: str = "alloy",
model: str = "tts-1-hd",
output_path: str = "output.mp3"
) -> str:
"""テキストから音声を生成"""
# 利用可能な声: alloy, echo, fable, onyx, nova, shimmer
response = client.audio.speech.create(
model=model, # tts-1(高速)or tts-1-hd(高品質)
voice=voice,
input=text,
speed=1.0 # 0.25〜4.0
)
response.stream_to_file(output_path)
return output_path
# 使用例: 通知メッセージの音声化
text_to_speech(
text="本日の売上レポートです。売上合計は1億2千万円で、前日比105%でした。",
voice="nova",
output_path="daily_report.mp3"
)
長文テキストのバッチ処理
def batch_tts(
texts: list[str],
voice: str = "alloy",
output_dir: str = "audio_output"
) -> list[str]:
"""複数テキストの一括音声生成"""
Path(output_dir).mkdir(parents=True, exist_ok=True)
output_files = []
for i, text in enumerate(texts):
# OpenAI TTSの入力上限は4096文字
if len(text) > 4096:
chunks = split_text_for_tts(text, max_chars=4000)
chunk_files = []
for j, chunk in enumerate(chunks):
path = f"{output_dir}/part_{i}_{j}.mp3"
text_to_speech(chunk, voice=voice, output_path=path)
chunk_files.append(path)
# チャンクを結合
merged_path = f"{output_dir}/merged_{i}.mp3"
merge_audio_files(chunk_files, merged_path)
output_files.append(merged_path)
else:
path = f"{output_dir}/audio_{i}.mp3"
text_to_speech(text, voice=voice, output_path=path)
output_files.append(path)
return output_files
def split_text_for_tts(text: str, max_chars: int = 4000) -> list[str]:
"""テキストを文単位で分割"""
sentences = text.replace("。", "。\n").split("\n")
chunks = []
current_chunk = ""
for sentence in sentences:
if len(current_chunk) + len(sentence) > max_chars:
if current_chunk:
chunks.append(current_chunk.strip())
current_chunk = sentence
else:
current_chunk += sentence
if current_chunk.strip():
chunks.append(current_chunk.strip())
return chunks
Google Cloud TTSの実装
SSMLを使った高度な音声制御
from google.cloud import texttospeech
def synthesize_with_ssml(
ssml_text: str,
output_path: str = "output.wav",
language_code: str = "ja-JP",
voice_name: str = "ja-JP-Neural2-B"
) -> str:
"""SSMLで音声を生成(ポーズ、強調、速度制御)"""
client = texttospeech.TextToSpeechClient()
input_text = texttospeech.SynthesisInput(ssml=ssml_text)
voice = texttospeech.VoiceSelectionParams(
language_code=language_code,
name=voice_name
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.LINEAR16,
speaking_rate=1.0,
pitch=0.0
)
response = client.synthesize_speech(
input=input_text,
voice=voice,
audio_config=audio_config
)
with open(output_path, "wb") as out:
out.write(response.audio_content)
return output_path
# SSML例: 自然なナレーション
ssml = """
<speak>
<p>
<s>本日の会議のアジェンダをお伝えします。</s>
<break time="500ms"/>
<s>第一に、<emphasis level="strong">売上報告</emphasis>です。</s>
<s>第二に、新商品の企画について議論します。</s>
<break time="300ms"/>
<s>それでは始めましょう。</s>
</p>
</speak>
"""
synthesize_with_ssml(ssml)
業務活用パターン
パターン1: eラーニングナレーション自動生成
def generate_elearning_audio(
script: list[dict],
voice: str = "nova"
) -> list[str]:
"""eラーニング用のナレーション音声を自動生成
script例:
[
{"slide": 1, "text": "本講座では..."},
{"slide": 2, "text": "最初に..."},
]
"""
audio_files = []
for item in script:
path = f"slide_{item['slide']}.mp3"
text_to_speech(
text=item["text"],
voice=voice,
output_path=path
)
audio_files.append({
"slide": item["slide"],
"audio": path,
"text": item["text"]
})
return audio_files
パターン2: 多言語カスタマーサポート
def generate_multilingual_announcement(
message_ja: str,
target_languages: list[str] = ["en", "zh", "ko"]
) -> dict[str, str]:
"""日本語メッセージを多言語音声に変換"""
results = {"ja": None}
# 日本語音声生成
results["ja"] = text_to_speech(message_ja, voice="nova", output_path="msg_ja.mp3")
# 翻訳 + 音声生成
for lang in target_languages:
translated = translate_text(message_ja, target_lang=lang)
voice = select_voice_for_language(lang)
path = f"msg_{lang}.mp3"
results[lang] = text_to_speech(translated, voice=voice, output_path=path)
return results
パターン3: レポートの音声化
日次レポート(テキスト)
│
▼
[要約生成] → LLMで3分以内に収まる要約を生成
│
▼
[TTS] → 自然な音声に変換
│
▼
[配信] → 社内ポッドキャストとして配信
倫理とガイドライン
音声AI利用時の注意点
| リスク | 説明 | 対策 |
|---|
| ディープフェイク | 本人の声を無断で複製 | 本人の同意を必須にする |
| なりすまし詐欺 | 経営者の声を模倣した詐欺 | 音声認証の多要素化 |
| 著作権侵害 | 声優・ナレーターの権利侵害 | ライセンス確認 |
| 偽情報拡散 | AIナレーションによる偽ニュース | AI生成の明示 |
社内ガイドライン(推奨)
1. AI生成音声であることを明示する
2. 個人の声のクローニングには書面での同意を取得する
3. 外部公開する音声には「AI Generated」の注記を含める
4. 声優・ナレーターの権利を尊重する
5. 定期的にガイドラインを見直す
まとめ
| 技術 | 概要 | 推奨ツール |
|---|
| 基本TTS | テキストから音声生成 | OpenAI TTS, Google Cloud TTS |
| SSML | ポーズ・強調・速度の制御 | Google Cloud TTS, Azure Speech |
| 声のクローニング | サンプルから声を再現 | ElevenLabs |
| 日本語特化 | 高品質日本語TTS | VOICEVOX, Google Cloud TTS |
チェックリスト
次のステップへ
次は動画分析の技術を学び、映像データからの情報抽出方法を習得します。
推定読了時間: 30分