# This file was auto-generated by Fern from our API Definition.

import contextlib
import json
import typing
from json.decoder import JSONDecodeError

from .. import core
from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from .errors.unprocessable_entity_error import UnprocessableEntityError
from .types.format import Format
from .types.http_validation_error import HttpValidationError
from .types.octave_version import OctaveVersion
from .types.posted_context import PostedContext
from .types.posted_utterance import PostedUtterance
from .types.posted_utterance_voice import PostedUtteranceVoice
from .types.return_tts import ReturnTts
from .types.timestamp_type import TimestampType
from .types.tts_output import TtsOutput

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawTtsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def synthesize_json(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ReturnTts]:
        """
        Synthesizes one or more input texts into speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        The response includes the base64-encoded audio and metadata in JSON format.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ReturnTts]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v0/tts",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ReturnTts,
                    parse_obj_as(
                        type_=ReturnTts,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    @contextlib.contextmanager
    def synthesize_file(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
        """
        Synthesizes one or more input texts into speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        The response contains the generated audio file in the requested format.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
            OK
        """
        with self._client_wrapper.httpx_client.stream(
            "v0/tts/file",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return HttpResponse(
                            response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
                        )
                    _response.read()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield _stream()

    @contextlib.contextmanager
    def synthesize_file_streaming(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
        """
        Streams synthesized speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
            OK
        """
        with self._client_wrapper.httpx_client.stream(
            "v0/tts/stream/file",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return HttpResponse(
                            response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
                        )
                    _response.read()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield _stream()

    @contextlib.contextmanager
    def synthesize_json_streaming(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[TtsOutput]]]:
        """
        Streams synthesized speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        The response is a stream of JSON objects including audio encoded in base64.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Yields
        ------
        typing.Iterator[HttpResponse[typing.Iterator[TtsOutput]]]
            Successful Response
        """
        with self._client_wrapper.httpx_client.stream(
            "v0/tts/stream/json",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[TtsOutput]]:
                try:
                    if 200 <= _response.status_code < 300:

                        def _iter():
                            for _text in _response.iter_lines():
                                try:
                                    if len(_text) == 0:
                                        continue
                                    yield typing.cast(
                                        TtsOutput,
                                        parse_obj_as(
                                            type_=TtsOutput,  # type: ignore
                                            object_=json.loads(_text),
                                        ),
                                    )
                                except Exception:
                                    pass
                            return

                        return HttpResponse(response=_response, data=_iter())
                    _response.read()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield _stream()

    @contextlib.contextmanager
    def convert_voice_file(
        self,
        *,
        audio: core.File,
        strip_headers: typing.Optional[bool] = OMIT,
        context: typing.Optional[PostedContext] = OMIT,
        voice: typing.Optional[PostedUtteranceVoice] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.List[TimestampType]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
        """
        Parameters
        ----------
        audio : core.File
            See core.File for more documentation

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        voice : typing.Optional[PostedUtteranceVoice]

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.List[TimestampType]]
            The set of timestamp types to include in the response. When used in multipart/form-data, specify each value using bracket notation: `include_timestamp_types[0]=word&include_timestamp_types[1]=phoneme`. Only supported for Octave 2 requests.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
            Successful Response
        """
        with self._client_wrapper.httpx_client.stream(
            "v0/tts/voice_conversion/file",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "strip_headers": strip_headers,
                "context": json.dumps(jsonable_encoder(context)),
                "voice": json.dumps(jsonable_encoder(voice)),
                "format": json.dumps(jsonable_encoder(format)),
                "include_timestamp_types": json.dumps(jsonable_encoder(include_timestamp_types)),
            },
            files={
                "audio": audio,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return HttpResponse(
                            response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
                        )
                    _response.read()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield _stream()

    @contextlib.contextmanager
    def convert_voice_json(
        self,
        *,
        strip_headers: typing.Optional[bool] = OMIT,
        audio: typing.Optional[core.File] = OMIT,
        context: typing.Optional[PostedContext] = OMIT,
        voice: typing.Optional[PostedUtteranceVoice] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.List[TimestampType]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[HttpResponse[typing.Iterator[TtsOutput]]]:
        """
        Parameters
        ----------
        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        audio : typing.Optional[core.File]
            See core.File for more documentation

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        voice : typing.Optional[PostedUtteranceVoice]

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.List[TimestampType]]
            The set of timestamp types to include in the response. When used in multipart/form-data, specify each value using bracket notation: `include_timestamp_types[0]=word&include_timestamp_types[1]=phoneme`. Only supported for Octave 2 requests.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Yields
        ------
        typing.Iterator[HttpResponse[typing.Iterator[TtsOutput]]]
            Successful Response
        """
        with self._client_wrapper.httpx_client.stream(
            "v0/tts/voice_conversion/json",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "strip_headers": strip_headers,
                "context": json.dumps(jsonable_encoder(context)),
                "voice": json.dumps(jsonable_encoder(voice)),
                "format": json.dumps(jsonable_encoder(format)),
                "include_timestamp_types": json.dumps(jsonable_encoder(include_timestamp_types)),
            },
            files={
                **({"audio": audio} if audio is not None else {}),
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        ) as _response:

            def _stream() -> HttpResponse[typing.Iterator[TtsOutput]]:
                try:
                    if 200 <= _response.status_code < 300:

                        def _iter():
                            for _text in _response.iter_lines():
                                try:
                                    if len(_text) == 0:
                                        continue
                                    yield typing.cast(
                                        TtsOutput,
                                        parse_obj_as(
                                            type_=TtsOutput,  # type: ignore
                                            object_=json.loads(_text),
                                        ),
                                    )
                                except Exception:
                                    pass
                            return

                        return HttpResponse(response=_response, data=_iter())
                    _response.read()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield _stream()


class AsyncRawTtsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def synthesize_json(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ReturnTts]:
        """
        Synthesizes one or more input texts into speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        The response includes the base64-encoded audio and metadata in JSON format.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ReturnTts]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v0/tts",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ReturnTts,
                    parse_obj_as(
                        type_=ReturnTts,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    @contextlib.asynccontextmanager
    async def synthesize_file(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
        """
        Synthesizes one or more input texts into speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        The response contains the generated audio file in the requested format.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
            OK
        """
        async with self._client_wrapper.httpx_client.stream(
            "v0/tts/file",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return AsyncHttpResponse(
                            response=_response,
                            data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
                        )
                    await _response.aread()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield await _stream()

    @contextlib.asynccontextmanager
    async def synthesize_file_streaming(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
        """
        Streams synthesized speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
            OK
        """
        async with self._client_wrapper.httpx_client.stream(
            "v0/tts/stream/file",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return AsyncHttpResponse(
                            response=_response,
                            data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
                        )
                    await _response.aread()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield await _stream()

    @contextlib.asynccontextmanager
    async def synthesize_json_streaming(
        self,
        *,
        utterances: typing.Sequence[PostedUtterance],
        context: typing.Optional[PostedContext] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.Sequence[TimestampType]] = OMIT,
        num_generations: typing.Optional[int] = OMIT,
        split_utterances: typing.Optional[bool] = OMIT,
        strip_headers: typing.Optional[bool] = OMIT,
        version: typing.Optional[OctaveVersion] = OMIT,
        instant_mode: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[TtsOutput]]]:
        """
        Streams synthesized speech using the specified voice. If no voice is provided, a novel voice will be generated dynamically. Optionally, additional context can be included to influence the speech's style and prosody.

        The response is a stream of JSON objects including audio encoded in base64.

        Parameters
        ----------
        utterances : typing.Sequence[PostedUtterance]
            A list of **Utterances** to be converted to speech output.

            An **Utterance** is a unit of input for [Octave](/docs/text-to-speech-tts/overview), and includes input `text`, an optional `description` to serve as the prompt for how the speech should be delivered, an optional `voice` specification, and additional controls to guide delivery for `speed` and `trailing_silence`.

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.Sequence[TimestampType]]
            The set of timestamp types to include in the response. Only supported for Octave 2 requests.

        num_generations : typing.Optional[int]
            Number of audio generations to produce from the input utterances.

            Using `num_generations` enables faster processing than issuing multiple sequential requests. Additionally, specifying `num_generations` allows prosody continuation across all generations without repeating context, ensuring each generation sounds slightly different while maintaining contextual consistency.

        split_utterances : typing.Optional[bool]
            Controls how audio output is segmented in the response.

            - When **enabled** (`true`), input utterances are automatically split into natural-sounding speech segments.

            - When **disabled** (`false`), the response maintains a strict one-to-one mapping between input utterances and output snippets.

            This setting affects how the `snippets` array is structured in the response, which may be important for applications that need to track the relationship between input text and generated audio segments. When setting to `false`, avoid including utterances with long `text`, as this can result in distorted output.

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        version : typing.Optional[OctaveVersion]
            Selects the Octave model version used to synthesize speech for this request. If you omit this field, Hume automatically routes the request to the most appropriate model. Setting a specific version ensures stable and repeatable behavior across requests.

            Use `2` to opt into the latest Octave capabilities. When you specify version `2`, you must also provide a `voice`. Requests that set `version: 2` without a voice will be rejected.

            For a comparison of Octave versions, see the [Octave versions](/docs/text-to-speech-tts/overview#octave-versions) section in the TTS overview.

        instant_mode : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Yields
        ------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[TtsOutput]]]
            Successful Response
        """
        async with self._client_wrapper.httpx_client.stream(
            "v0/tts/stream/json",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            json={
                "context": convert_and_respect_annotation_metadata(
                    object_=context, annotation=PostedContext, direction="write"
                ),
                "format": convert_and_respect_annotation_metadata(object_=format, annotation=Format, direction="write"),
                "include_timestamp_types": include_timestamp_types,
                "num_generations": num_generations,
                "split_utterances": split_utterances,
                "strip_headers": strip_headers,
                "utterances": convert_and_respect_annotation_metadata(
                    object_=utterances, annotation=typing.Sequence[PostedUtterance], direction="write"
                ),
                "version": version,
                "instant_mode": instant_mode,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[TtsOutput]]:
                try:
                    if 200 <= _response.status_code < 300:

                        async def _iter():
                            async for _text in _response.aiter_lines():
                                try:
                                    if len(_text) == 0:
                                        continue
                                    yield typing.cast(
                                        TtsOutput,
                                        parse_obj_as(
                                            type_=TtsOutput,  # type: ignore
                                            object_=json.loads(_text),
                                        ),
                                    )
                                except Exception:
                                    pass
                            return

                        return AsyncHttpResponse(response=_response, data=_iter())
                    await _response.aread()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield await _stream()

    @contextlib.asynccontextmanager
    async def convert_voice_file(
        self,
        *,
        audio: core.File,
        strip_headers: typing.Optional[bool] = OMIT,
        context: typing.Optional[PostedContext] = OMIT,
        voice: typing.Optional[PostedUtteranceVoice] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.List[TimestampType]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
        """
        Parameters
        ----------
        audio : core.File
            See core.File for more documentation

        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        voice : typing.Optional[PostedUtteranceVoice]

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.List[TimestampType]]
            The set of timestamp types to include in the response. When used in multipart/form-data, specify each value using bracket notation: `include_timestamp_types[0]=word&include_timestamp_types[1]=phoneme`. Only supported for Octave 2 requests.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
            Successful Response
        """
        async with self._client_wrapper.httpx_client.stream(
            "v0/tts/voice_conversion/file",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "strip_headers": strip_headers,
                "context": json.dumps(jsonable_encoder(context)),
                "voice": json.dumps(jsonable_encoder(voice)),
                "format": json.dumps(jsonable_encoder(format)),
                "include_timestamp_types": json.dumps(jsonable_encoder(include_timestamp_types)),
            },
            files={
                "audio": audio,
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
                try:
                    if 200 <= _response.status_code < 300:
                        _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
                        return AsyncHttpResponse(
                            response=_response,
                            data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
                        )
                    await _response.aread()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield await _stream()

    @contextlib.asynccontextmanager
    async def convert_voice_json(
        self,
        *,
        strip_headers: typing.Optional[bool] = OMIT,
        audio: typing.Optional[core.File] = OMIT,
        context: typing.Optional[PostedContext] = OMIT,
        voice: typing.Optional[PostedUtteranceVoice] = OMIT,
        format: typing.Optional[Format] = OMIT,
        include_timestamp_types: typing.Optional[typing.List[TimestampType]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[TtsOutput]]]:
        """
        Parameters
        ----------
        strip_headers : typing.Optional[bool]
            If enabled, the audio for all the chunks of a generation, once concatenated together, will constitute a single audio file. Otherwise, if disabled, each chunk's audio will be its own audio file, each with its own headers (if applicable).

        audio : typing.Optional[core.File]
            See core.File for more documentation

        context : typing.Optional[PostedContext]
            Utterances to use as context for generating consistent speech style and prosody across multiple requests. These will not be converted to speech output.

        voice : typing.Optional[PostedUtteranceVoice]

        format : typing.Optional[Format]
            Specifies the output audio file format.

        include_timestamp_types : typing.Optional[typing.List[TimestampType]]
            The set of timestamp types to include in the response. When used in multipart/form-data, specify each value using bracket notation: `include_timestamp_types[0]=word&include_timestamp_types[1]=phoneme`. Only supported for Octave 2 requests.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Yields
        ------
        typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[TtsOutput]]]
            Successful Response
        """
        async with self._client_wrapper.httpx_client.stream(
            "v0/tts/voice_conversion/json",
            base_url=self._client_wrapper.get_environment().base,
            method="POST",
            data={
                "strip_headers": strip_headers,
                "context": json.dumps(jsonable_encoder(context)),
                "voice": json.dumps(jsonable_encoder(voice)),
                "format": json.dumps(jsonable_encoder(format)),
                "include_timestamp_types": json.dumps(jsonable_encoder(include_timestamp_types)),
            },
            files={
                **({"audio": audio} if audio is not None else {}),
            },
            request_options=request_options,
            omit=OMIT,
            force_multipart=True,
        ) as _response:

            async def _stream() -> AsyncHttpResponse[typing.AsyncIterator[TtsOutput]]:
                try:
                    if 200 <= _response.status_code < 300:

                        async def _iter():
                            async for _text in _response.aiter_lines():
                                try:
                                    if len(_text) == 0:
                                        continue
                                    yield typing.cast(
                                        TtsOutput,
                                        parse_obj_as(
                                            type_=TtsOutput,  # type: ignore
                                            object_=json.loads(_text),
                                        ),
                                    )
                                except Exception:
                                    pass
                            return

                        return AsyncHttpResponse(response=_response, data=_iter())
                    await _response.aread()
                    if _response.status_code == 422:
                        raise UnprocessableEntityError(
                            headers=dict(_response.headers),
                            body=typing.cast(
                                HttpValidationError,
                                parse_obj_as(
                                    type_=HttpValidationError,  # type: ignore
                                    object_=_response.json(),
                                ),
                            ),
                        )
                    _response_json = _response.json()
                except JSONDecodeError:
                    raise ApiError(
                        status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
                    )
                raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

            yield await _stream()
