> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cartesia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 継続による入力ストリーミング

> Sonic TTS に入力テキストをストリーミングする方法を学びます。

export const AudioPlayer = ({src}) => {
  const [hasError, setHasError] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  useEffect(() => {
    setIsLoading(true);
    setHasError(false);
  }, [src]);
  const handleCanPlay = () => {
    setIsLoading(false);
    setHasError(false);
  };
  const handleError = () => {
    setIsLoading(false);
    setHasError(true);
  };
  const audioClasses = ["w-full", "rounded-full", isLoading || hasError ? "opacity-50" : "opacity-100", hasError ? "pointer-events-none" : "", "transition-opacity"].join(" ");
  return <div className="my-4">
      <audio src={src} controls onCanPlay={handleCanPlay} onError={handleError} className={audioClasses} />

      {isLoading && !hasError && <p className="text-xs text-gray-500 dark:text-gray-400 mt-2 pl-4">Loading audio...</p>}
    </div>;
};

多くのリアルタイムなユースケースでは、入力テキストを事前に用意できません。たとえば、言語モデルで逐次生成する場合などです。このようなケースに対応するため、Cartesia は *継続* (continuations) と呼ばれる機能で入力ストリーミングをサポートしています。

<Info>
  このガイドでは、TTS モデルの観点から入力ストリーミングの仕組みを説明します。入力ストリーミングを実装したいだけの場合は、*contexts* を使用して継続を実装している [WebSocket API リファレンス](/api-reference/tts/websocket) を参照してください。

  Python と TypeScript の SDK は `continue` フラグを自動で処理します。`ctx.push()` は各チャンクを `continue: true` で送信し、`ctx.no_more_inputs()` は `continue: false` を送信します。動作するコードは [WebSocket continuations の例](/examples/tts-websocket-continuations) を参照してください。
</Info>

## 継続

継続とは、すでに生成された音声を延長する生成のことです。前の生成が終了したところから生成を継続し、前の生成の *プロソディ* を維持するため、継続と呼ばれます。

継続を使わない場合、プロソディが突然変化し、音声に継ぎ目が発生します。

<Note>
  プロソディとは、音声のリズム、イントネーション、ストレスを指します。音声を自然に流れさせ、人間らしく聞こえさせる要素です。
</Note>

LLM を使用しており、1 秒の間隔を空けて 3 つのパートに分けて原稿が生成されるとします。

1. `Hello, my name is Sonic.`
2. ` It's very nice`
3. ` to meet you.`

原稿全体の音声を生成するために、各パートを個別に生成して結合することを考えるかもしれません。

<Frame caption="図 1: 原稿を個別に生成して結合する。">
  <img src="https://mintcdn.com/cartesia-2650f86a/GOsvXpql8JfAlgjy/assets/images/concepts_continuations_without_continuations.png?fit=max&auto=format&n=GOsvXpql8JfAlgjy&q=85&s=39aea327ca243fe43b6633c5614eb497" alt="no_continuations" width="4198" height="1794" data-path="assets/images/concepts_continuations_without_continuations.png" />
</Frame>

残念ながら、結果として得られる音声はプロソディが突然変わり、ペースも不自然になります。

<AudioPlayer src="/assets/audio/continuations/generation_no_continuation.wav">
  Your browser does not support the audio element.
</AudioPlayer>

次に、同じ原稿を継続を使って試してみましょう。セットアップは次のようになります。

<Frame caption="図 2: 継続を使って原稿を生成する。">
  <img src="https://mintcdn.com/cartesia-2650f86a/GOsvXpql8JfAlgjy/assets/images/concepts_continuations_with_continuations.png?fit=max&auto=format&n=GOsvXpql8JfAlgjy&q=85&s=a14323d45501e56a96ed5b9c672aaa85" alt="continuations" width="4767" height="1764" data-path="assets/images/concepts_continuations_with_continuations.png" />
</Frame>

結果は次のとおりです。

<AudioPlayer src="/assets/audio/continuations/generation_continuation.wav">
  Your browser does not support the audio element.
</AudioPlayer>

ご覧のとおり、この出力はシームレスで自然に聞こえます。

<Check>
  継続は任意の数の入力にスケールできます。上限はありません。
</Check>

## 注意点: 結合したときに有効な原稿になる必要がある

これは、`"Hello, world!"` の後に `" How are you?"` (先頭の空白に注意) を続けることはできますが、`"How are you?"` を続けることはできないということです。結合すると `"Hello, world!How are you?"` という無効な原稿になるためです。

実際には、ストリームする入力で空白と句読点を維持する必要があります。

<Warning>
  **完全な文は終止符 (例: `.`、`?`、`!`) で終えてください。**

  ストリームされたチャンクが文末の句読点で終わっていない場合、モデルは多くの場合それを未完成の文として扱います。これにより、以下が発生する可能性があります。

  * **追加のレイテンシ:** テキストが自動入力バッファに保持され、モデルがより明確な区切りを見つけるか `max_buffer_delay_ms` (**デフォルトは 3000ms**) が経過するまで待機するため、音声の開始が遅れる場合があります。
  * **音声のアーティファクト:** モデルは自然な文末を想定しているため、終止符がないと生成される音声が奇妙または歪んだ音で終わる場合があります。

  ユーザーに向けた発話が完了したら、最後のセグメントに終止符を付けてください (適切なタイミングでコンテキストにこれ以上テキストが来ないことを通知してください。たとえば SDK での `no_more_inputs()` や WebSocket での `continue: false` など)。
</Warning>

## `max_buffer_delay_ms` による自動バッファリング

LLM から単語ごとまたはトークンごとに入力をストリーミングする場合、モデルにとって最適なテキストの長さになるまでバッファリングします。デフォルトのバッファは 3000ms です。これを変更したい場合は `max_buffer_delay_ms` パラメータを使えますが、*この変更は推奨しません*。

<Warning>
  バッファリングと `speed` または `volume` の [SSML タグ](/build-with-cartesia/capability-guides/ssml-tags) を併用する場合は、小数値が分割されないようにしてください。
  `1.0` を `1`、`.`、`0` として送信すると、意図しない失敗モードが発生します。
</Warning>

### 仕組み

設定すると、モデルは高品質な音声を生成するのに十分なコンテキストがあると確信するか、バッファ遅延が経過するか、いずれか早い方まで入力テキストチャンクをバッファリングします。

このバッファがない場合、モデルは各入力ですぐに生成を開始するため、入力が非常に小さい (単語やトークン単位) と、音声がぶつ切りになったり、プロソディが不自然になったりする可能性があります。

### 設定

* **範囲**: 0-5000ms の値がサポートされています
* **デフォルト**: 3000ms

次の場合に*のみ*使用してください。

* クライアント側でカスタムバッファリングを行っている場合は、0 に設定できます。
* 3000ms でもぶつ切り感がある場合は、より高い値を試してください。

```js lines theme={null}
// Example WebSocket request with `max_buffer_delay_ms`
{
  "model_id": "sonic-3.5",
  "transcript": "Hello",  // First word/token
  "voice": {
    "mode": "id",
    "id": "a0e99841-438c-4a64-b679-ae501e7d6091"
  },
  "context_id": "my-conversation-123",
  "continue": true,
  "max_buffer_delay_ms": 3000  // Buffer up to 3000ms
}
```

継続とデフォルトの `max_buffer_delay_ms=3000` で次の原稿を試してみましょう: `['Hello', 'my name', 'is Sonic.', "It's ", 'very ', 'nice ', 'to ', 'meet ', 'you.']`

<AudioPlayer src="/assets/audio/continuations/generation_multiple_small_inputs.wav">
  Your browser does not support the audio element.
</AudioPlayer>
