# 音声合成
> プリセットまたはクローンしたボイスで、テキストを音声に合成します。

プリセットまたはクローンしたボイスで、テキストを音声に合成します。

## Agent の主経路

Universal Skill から MCP ツール `beatra.speech.synthesize` を使います。この
ツールは課金対象で、非同期タスクを返します。

1. まずボイスを選びます。`beatra.voices.list` がプリセットとクローンの
   `voice_id` と試聴 URL を返します。
2. モデル・言語・フォーマット・価格が結果に影響する場合は
   `capability: "text_to_speech"` で `beatra.models.list` を呼びます。
   そうでなければ `model: "auto"` を使うか `model` を省略します。
3. 不透明な `client_request_id` を 1 つ作り、最終的な引数を一度だけ送信します。
4. 返されたタスクを `beatra.tasks.get` で終端状態までポーリングします。

## AI ガイド

AI integration guide: https://docs.beatra.ai/llms/audio-text-to-speech.md

## ツール引数

```json
{
  "voice": "voice_01JX...",
  "input": "Welcome to Beatra — make your first call in three minutes.",
  "language": "en-US",
  "format": "mp3",
  "speed": 1.0,
  "client_request_id": "tts-opaque-1"
}
```

`voice` には[ボイス管理](https://docs.beatra.ai/ja/docs/capabilities/speech/voices)が返す任意の
`voice_id` を指定できます（プリセットでも[クローンボイス](https://docs.beatra.ai/ja/docs/capabilities/speech/voice-clone)でも可）。
各ボイスは 1 つのエンジンに属します（`compatible_models`）。モデルによっては、ボイスごとに従うコントロールが異なり、
ボイスの `persona` に書かれています。
ストリーミングとリアルタイム会話はこの機能には含まれません。

## マークアップ

`input` には閉じたトークン集合を書けます。トークンは 50,000 文字の上限と、
加重文字の課金の両方に数えます。語彙と各モデルの値域は
`beatra.models.list` のモデルカード `constraints.script_markup` です。
同じマークアップがすべての音声モデルで使えます。モデルが表現できないものは除去または無視され、
警告が返ります（近似で置き換えることはありません）。このページ下部の「モデル固有のオプション」は
`model_options` のフィールドであり、マークアップではありません。

- `{pause <seconds>}` — 無音。小数は最大 2 桁で、モデルカードの `script_markup.pause.range` の範囲内（最長 99.99 秒のモデルも 10 秒のモデルもあり、超えると課金前に拒否されます）。テキスト全体の先頭・末尾に置く場合、または 2 つの pause の間に読めるテキストがない場合は拒否されます。
- 音のタグ：`{laugh}` 笑い声、`{chuckle}` 軽い笑い、`{sigh}` ため息、`{breath}` 息継ぎ、`{cough}` 咳、`{clear-throat}` 咳払い、`{gasp}` 息をのむ音、`{groan}` うめき声、`{inhale}` 吸気、`{exhale}` 呼気、`{pant}` 荒い息、`{sniff}` 鼻をすする音、`{hmm}` 「うーん」（迷い・考え中）。`script_markup.tags` にモデルが出せるタグが並びます。対応していないモデルではタグを取り除き（読み上げません）、`markup_degraded` 警告を返します。
- `{pron <word> <reading>}` — マークした箇所だけ語の読みを固定します。同じ語のほかの箇所は既定の読みのままで、1 回のリクエストで同じ字に別々の読みを指定できます。読み記法は拼音です。音節を直結し、各音節は声調数字 1–5 で終わり、ü は v、中国語の語は 1 文字につき 1 音節です。それ以外の記法は未対応です。例：`孩子{pron 长 zhang3}大了，头发也很{pron 长 chang2}。`
- `{sub <word> <spoken text>}` — マークした箇所の語を指定した文言（最大 100 文字）で読み上げます。字幕には元の語が表示されます。ブランド名、略語、英単語、1 桁ずつ読ませたい数字に使います。例：`{sub W3C 万维网联盟}`。
- `{{` — 文字どおりの左波括弧です。`{{` と書いた位置は `{` として読まれ、この 2 文字自体はトークンとして解析されません。その後のテキストは通常どおり解析されるため、左波括弧だけをエスケープし、右波括弧はそのまま書いてください。

各モデルカードの `constraints.limitations` には、そのモデルの制限が文章で書かれています。呼び出すモデルのカードを読んでください。例：

- 音量・速度・音高・感情はリクエスト全体に適用され、特定の一文や一語には効きません。部分的に変えたい場合は複数回の呼び出しに分ける（それぞれパラメータと音声ファイルが別になります）か、テキストの書き換え（省略記号・短い文・言い回し）で調整してください。
- モデルによっては、長いテキスト（3,000 文字を超えると非同期パス）で高品質な数値正規化が使えない、または `{pause}`・`{pron}` マークアップを取り除きます（警告あり）。必要な場合は段落の区切りで 3,000 文字以下のリクエストに分けてください。

## 演技の指示と前の文

次の 2 つのオプションフィールドは、この音声をどう読むかを伝えます。従うモデルはモデルカードの `controls` に並びます（関連する数値は `constraints.direction_max_characters` と `constraints.previous_text_tail_characters`）。

- `direction` — リクエスト全体への自然言語の演技指示。例：`像在耳边说悄悄话一样，轻声地说`、`read it like breaking news`。一、二文に収めてください。`direction_max_characters` を超える指示は無視され、警告が返ります。実際の効果はモデル、ボイス、テキストによります。音量は `volume` で指定してください。
- `previous_text` — この音声の直前に来るテキスト（会話の前の台詞、前の段落）で、別々に合成した音声の口調をつなげます。長さは自由で、モデルは末尾の `previous_text_tail_characters` 文字だけを使います。読み上げられません。

どちらも課金されず、リクエストを失敗させることもありません。フィールドに従わないモデル・ボイス・パスはそれを無視して `option_ignored` 警告を返し、音声は通常どおり生成されます。モデルによっては、ボイス（たとえばキャラクター系ボイスはどちらにも従わない）にも左右されます。モデルカードの `constraints.limitations` に書かれています。`emotion` も同じで、モデルやボイスが表現できない感情は無視され、警告が返ります。課金前にボイスがこれらのコントロールに従うか知りたい場合は、同じリクエストを下記の validate に送ってください。同じ警告が無料で返ります。

課金する送信の前に `beatra.speech.validate` または
`POST /v1/audio/speech/validate` を使えます。同じ解析と警告チェックを行い、
加重文字数と必要クレジットを返します。タスクは作成せず、クレジットも消費せず、
音声エンジンも呼び出しません。`Idempotency-Key` は不要です。

warnings があるとき、それは 202（冪等リプレイを含む）、
`GET /v1/tasks/{task_id}`、`beatra.tasks.get`、顧客コールバックの
`task.warnings` に出ます。タスク一覧、`expand`、アカウント詳細、admin は
保証しません。字幕の `text_begin` / `text_end` はエンジンが実際に読んだテキスト
（マークアップを各エンジンの形へコンパイルしたもの、または取り除いたもの）への
オフセットであり、送信原文へはマッピングし直しません。字幕の区間がこのテキストと
一致する場合、`text` では `{pron}`・`{sub}` の語が元の表記で表示され、音のタグは含まれません。
課金の文字数は後述の「モデル・コントロール・コスト」の節を参照してください。`output.characters` はエンジンが
実際に読んだ文字数のため、二つの数は異なり得ます。

## モデル・コントロール・コスト

共通コントロールは `input`（必須、≤50,000 文字）、`voice`（必須）、
`language`、`format`（デフォルト `mp3`。ほかの対応形式はモデルカードの `constraints.formats`）、
`speed`（0.5–2.0）、`volume`（モデルカードの `constraints.volume` の範囲内。例：>0–10、0.5–2。範囲外は課金前に拒否されます）、`pitch`（−1–1、正規化：0 = 元の音高、
−1 は最低、1 はモデルが許容する最高音高。細かい調整は 0.25 のような小数）,
`emotion`、`sample_rate`、`subtitle_enable`（デフォルト `false`。`true` にすると
文単位の字幕が `output.subtitles` として音声とともに返ります。無料です。選んだボイスや言語で
モデルが字幕を作れない場合は課金前に拒否され、`constraints.limitations` にその条件が書かれています。
実行時に字幕ファイルを生成できなかった場合も音声は届き、`output.subtitles` が付かないだけです）。
`language` はモデルによって一部しか使われません。選んだモデルでの扱いは `constraints.limitations` に
書かれています。各コントロールは選択したモデルのメタデータに従ってのみ
使用します。フォーマットによって対応サンプリングレートは異なります
（例：`opus` はモデルによって 8/16/24 kHz のみ、または固定の 48 kHz で `sample_rate` を受け付けません）。すべてのフォーマットに共通のレート一覧を前提にせず、モデルカードの
`constraints.sample_rates_by_format` を参照してください。

選択可能なモデル、対応言語、フォーマット、サンプルレート、価格の最新の
事実源は `beatra.models.list` です。モデルカタログや価格表を agent の
プロンプトに複製しないでください。

音声はリクエスト見積で前払いされ、加重文字数に応じて**線形**に課金されます
（単価は加重文字 1,000 あたりで提示）：漢字 1 文字は 2、それ以外は 1 と数えます。送信した原文（マークアップを含む）で数えます。エンジンが受け取る制御テキストを長さで課金するモデルでは、エンジンに送るテキストのほうが長ければそちらで数えます。そこでは pause や読みが制御タグになり、タグを含む（または本文が `<speak` で始まる）リクエストは全文がその形式で送られます（`&`・`<`・`>` はエスケープされます）。正確な文字数は validate が返します。

## モデル固有のオプション

`model_options` は特定のモデル系列だけが実行するオプションで、系列名で区切ります。モデルカードの `controls` に、そのモデルが実行するキーが並びます（例：`model_options.doubao.explicit_dialect`）。別系列のキーは効きません。モデルが `option_ignored` 警告で知らせることがあります。

### MiniMax：読み辞書

難読漢字や複数の読みを持つ漢字は、同音の漢字に書き換えなくても、読みを直接指定できます:

```json
{
  "model_options": {
    "minimax": {
      "pronunciation_dict": {
        "tone": ["湛/(zhan4)", "晞/(xi1)", "厌/(yan1)"]
      }
    }
  }
}
```

形式は `文字/(ピンイン+声調番号)`。声調番号は四声が 1–4、軽声が 5 です。
辞書の項目はリクエスト内のその語のすべての箇所に適用されます。1 か所だけ直す場合は、
上記の `{pron}` マークアップを使ってください。MiniMax 系モデルのみ対応で、
他のモデルはこのフィールドを無視します。

### Doubao

- `model_options.doubao.explicit_dialect` — `beijing`、`dongbei`、`henan`、`shaanxi`、`shanghai`、`sichuan`、`tianjin`（広東語は `language: "yue-HK"`）。方言を話せるのは `languages_supported` に `yue` を含むボイスだけで、ほかのボイスは課金前に拒否されます。
- `model_options.doubao.silence_duration` — 最後の語のあとに足す無音（0–30,000 ミリ秒）。
- `model_options.doubao.explicit_language` — 読み上げ言語を強制します（`zh-cn`、`en`、`ja`、`es-mx`、`ko`、`de`、`fr` など）。これはヒントではなくフィルターです。ほかの言語の文は飛ばされ、ボイスが読めないテキストは音声になりません（タスクは失敗し、返金されます）。`nl`、`no`、`uk`、`fi`、`da`、`cs`、`hu`、`el`、`ro`、`hi`、`es-es` は中国語（`zh_…`）のプリセットボイスでのみ有効です。長いテキストで使えるのは `zh-cn`、`en`、`es-mx`、`id`、`pt-br` だけです。
- `model_options.doubao.latex_parser` — `"v2"` で LaTeX の数式を読み上げます（教育向け）。
- `model_options.doubao.pronunciation_dict` — `{"tone": ["北京/(bei3)(jing1)", "omg/oh my god"]}`：最大 5,000 件で、その語のすべての箇所に適用されます（読みまたは置き換え文言）。1 か所だけ直すなら `{pron}` を使ってください。

テキストで `{pause}` や `{pron}` を使う場合はマークアップが優先されます。`latex_parser` と `pronunciation_dict` は無視され、警告が返ります。エンジンがマークアップの変換後の形式と同時に扱えないためです。

## 言語

`language` はオプションのプロバイダー中立な BCP-47 タグです（例：`zh-CN`、
`yue-HK`、`en-US`）。Beatra は主言語サブタグを選択モデルと照合します。
省略するとボイスまたはプロバイダーが選択します。自動言語検出を明示的に
要求する場合のみ固定値 `auto` を渡してください（モデルカードの
`constraints.language_auto` が対応可否を示します）。未対応の言語は黙って
置き換えられず、拒否されます。

`language` の使い方はモデルによって異なります。ボイスへの認識ヒントとして使うモデルもあれば、
中国語と英語を既定で読み、それ以外の言語では `language` で言語認識をオンにする（たとえば中国語の
ボイスが日本語を読む場合、渡さないと読めないことがあります）とともに方言（`yue`）を選ぶモデルもあります。
後者では各ボイスが `languages_supported` の言語だけを読み、ボイスが話せない言語を渡すと
`option_ignored` 警告が返ります。結果が失敗にしかならない場合は課金前に拒否されます（広東語を話せないボイスへの
広東語、ボイスが読めない言語の長いテキスト）。どちらかはモデルカードの `constraints.limitations` で確認してください。

現在の音声モデルは以下の最大 40 言語をカバーし、各モデルはその一部に対応します。モデル別のリアルタイムな
事実源は `beatra.models.list` の `constraints.supported_languages` です。

| コード | 言語 | コード | 言語 |
| --- | --- | --- | --- |
| `zh` | 中国語 | `tr` | トルコ語 |
| `yue` | 広東語 | `nl` | オランダ語 |
| `en` | 英語 | `uk` | ウクライナ語 |
| `es` | スペイン語 | `th` | タイ語 |
| `fr` | フランス語 | `pl` | ポーランド語 |
| `ru` | ロシア語 | `ro` | ルーマニア語 |
| `de` | ドイツ語 | `el` | ギリシャ語 |
| `pt` | ポルトガル語 | `cs` | チェコ語 |
| `ar` | アラビア語 | `fi` | フィンランド語 |
| `it` | イタリア語 | `hi` | ヒンディー語 |
| `ja` | 日本語 | `bg` | ブルガリア語 |
| `ko` | 韓国語 | `da` | デンマーク語 |
| `id` | インドネシア語 | `he` | ヘブライ語 |
| `vi` | ベトナム語 | `ms` | マレー語 |
| `fa` | ペルシア語 | `sk` | スロバキア語 |
| `sv` | スウェーデン語 | `hr` | クロアチア語 |
| `fil` | フィリピン語 | `hu` | ハンガリー語 |
| `no` | ノルウェー語 | `sl` | スロベニア語 |
| `ca` | カタルーニャ語 | `nn` | ニーノシュク |
| `ta` | タミル語 | `af` | アフリカーンス語 |

## タスクの状態とリカバリー

`queued` と `running` は失敗ではありません。同じ `task_id` をポーリングし
続け、実行中だからといって代替リクエストを送らないでください。作成応答を
失った場合は、同じ `client_request_id` で同一の引数を再送します。入力が
少しでも変わったら新しい ID を使います。失敗したタスクは自動で返金されます。
音声アーティファクト、実際のモデル、課金額は終端状態のタスク応答からのみ
返してください。アーティファクト URL は CDN アドレスです——速やかに自分の
ストレージへコピーしてください。

## REST で呼び出す

プロトコル直結の統合は `POST /v1/audio/speech` と共有タスクエンドポイントを
使えます。生成された[API 定義](https://docs.beatra.ai/ja/docs/api-reference/operations/audio/text_to_speech_v1_audio_speech_post)
に従ってください。推奨の統合方法は Skill + MCP です。REST は Agent ではないカスタム
アプリケーション向けです。
