o
    il8                  
   @   sr  d Z ddlZddlZddlZddlmZmZ ddlmZm	Z	m
Z
 ddlZddlmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZ dd	lmZ dd
lmZmZm Z  ddl!m"Z" ddl#m$Z$ zddl%m&Z& ddl'm(Z(m)Z)m*Z* ddl+m,Z, W n  e-y Z. ze/de.  e/d e0de. dZ.[.ww dZ1de dZ2eG dd deZ3G dd de"Z4dS )z+Hume Text-to-Speech service implementation.    N)	dataclassfield)AnyAsyncGeneratorOptional)logger)	BaseModel)version)CancelFrameEndFrameFrameInterruptionFrame
StartFrameTTSAudioRawFrameTTSStoppedFrame)FrameDirection)	NOT_GIVENTTSSettings	_NotGiven)
TTSService)
traced_tts)AsyncHumeClient)	FormatPcmPostedUtterancePostedUtteranceVoiceWithId)TimestampMessagezException: zAIn order to use Hume, you need to `pip install pipecat-ai[hume]`.zMissing module: i  pipecat)zX-Hume-Client-NamezX-Hume-Client-Versionc                   @   sl   e Zd ZU dZedd dZedB eB ed< edd dZ	e
dB eB ed< ed	d dZe
dB eB ed
< dS )HumeTTSSettingszSettings for HumeTTSService.

    Parameters:
        description: Natural-language acting directions (up to 100 characters).
        speed: Speaking-rate multiplier (0.5-2.0).
        trailing_silence: Seconds of silence to append at the end (0-5).
    c                   C      t S Nr    r!   r!   M/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/services/hume/tts.py<lambda>=       zHumeTTSSettings.<lambda>)default_factoryNdescriptionc                   C   r   r   r    r!   r!   r!   r"   r#   >   r$   speedc                   C   r   r   r    r!   r!   r!   r"   r#   ?   r$   trailing_silence)__name__
__module____qualname____doc__r   r&   strr   __annotations__r'   floatr(   r!   r!   r!   r"   r   3   s
   
 "r   c                       s&  e Zd ZU dZeZeed< G dd deZddde	ddde
e de
e d	e
e d
e
e de
e ddf fddZdefddZdeddf fddZdd Zdeddf fddZdeddf fddZejfdedef fddZdededdfdd Zed!ed"edeedf fd#d$Z  Z S )%HumeTTSServicea  Hume Octave Text-to-Speech service.

    Streams PCM audio via Hume's HTTP output streaming (JSON chunks) endpoint
    using the Python SDK and emits ``TTSAudioRawFrame`` frames suitable for Pipecat transports.

    Supported features:

    - Generates speech from text using Hume TTS.
    - Streams PCM audio.
    - Supports word-level timestamps for precise audio-text synchronization.
    - Supports dynamic updates of voice and synthesis parameters at runtime.
    - Provides metrics for Time To First Byte (TTFB) and TTS usage.
    	_settingsc                   @   sB   e Zd ZU dZdZee ed< dZee	 ed< dZ
ee	 ed< dS )zHumeTTSService.InputParamsa  Optional synthesis parameters for Hume TTS.

        .. deprecated:: 0.0.105
            Use ``settings=HumeTTSService.Settings(...)`` instead.

        Parameters:
            description: Natural-language acting directions (up to 100 characters).
            speed: Speaking-rate multiplier (0.5-2.0).
            trailing_silence: Seconds of silence to append at the end (0-5).
        Nr&   r'   r(   )r)   r*   r+   r,   r&   r   r-   r.   r'   r/   r(   r!   r!   r!   r"   InputParamsT   s
   
 r2   N)api_keyvoice_idparamssample_ratesettingsr3   r4   r5   r6   r7   returnc                   s   |pt d}|std|tkrtdt d|  | jddddddd}|dur4| dd ||_|durK| d	 |sK|j	|_	|j
|_
|j|_|durT|| t jd|d
dd|d| tjtd| _t|| jd| _d| _d| _dS )a  Initialize the HumeTTSService.

        Args:
            api_key: Hume API key. If omitted, reads the ``HUME_API_KEY`` environment variable.
            voice_id: ID of the voice to use. Only voice IDs are supported; voice names are not.

                .. deprecated:: 0.0.105
                    Use ``settings=HumeTTSService.Settings(voice=...)`` instead.

            params: Optional synthesis controls (acting instructions, speed, trailing silence).

                .. deprecated:: 0.0.105
                    Use ``settings=HumeTTSService.Settings(...)`` instead.

            sample_rate: Output sample rate for emitted PCM frames. Defaults to 48_000 (Hume).
            settings: Runtime-updatable settings. When provided alongside deprecated
                parameters, ``settings`` values take precedence.
            **kwargs: Additional arguments passed to the parent class.
        HUME_API_KEYzAHumeTTSService requires an API key (env HUME_API_KEY or api_key=)zHume TTS streams at z Hz; configured sample_rate=N)modelvoicelanguager&   r'   r(   r4   r;   r5   FT)r6   push_text_framespush_stop_framespush_start_framer7   )headers)r3   httpx_client            r!   )osgetenv
ValueErrorHUME_SAMPLE_RATEr   warningSettings"_warn_init_param_moved_to_settingsr;   r&   r'   r(   apply_updatesuper__init__httpxAsyncClientDEFAULT_HEADERS_http_clientr   _client_audio_bytes_cumulative_time)selfr3   r4   r5   r6   r7   kwargsdefault_settings	__class__r!   r"   rM   d   sN   



zHumeTTSService.__init__c                 C   s   dS )zoCan generate metrics.

        Returns:
            True if metrics can be generated, False otherwise.
        Tr!   rU   r!   r!   r"   can_generate_metrics   s   z#HumeTTSService.can_generate_metricsframec                    s    t  |I dH  |   dS )zNStart the service.

        Args:
            frame: The start frame.
        N)rL   start_reset_staterU   r\   rX   r!   r"   r]      s   zHumeTTSService.startc                 C   s
   d| _ dS )zReset internal state variables.rC   N)rT   rZ   r!   r!   r"   r^      s   
zHumeTTSService._reset_statec                    @   t  |I dH  t| dr| jr| j I dH  dS dS dS )zaStop the service and cleanup resources.

        Args:
            frame: The end frame.
        NrQ   )rL   stophasattrrQ   acloser_   rX   r!   r"   ra      
   zHumeTTSService.stopc                    r`   )zfCancel the service and cleanup resources.

        Args:
            frame: The cancel frame.
        NrQ   )rL   cancelrb   rQ   rc   r_   rX   r!   r"   re      rd   zHumeTTSService.cancel	directionc                    sT   t  ||I dH  t|ttfr&|   t|tr(| dgI dH  dS dS dS )zPush a frame and handle state changes.

        Args:
            frame: The frame to push.
            direction: The direction to push the frame.
        N)Resetr   )rL   
push_frame
isinstancer   r   r^   add_word_timestamps)rU   r\   rf   rX   r!   r"   rh      s   
zHumeTTSService.push_framekeyvaluec                    s  t   t d t jdtdd W d   n1 sw   Y  |p%d }h d}||v ri }|dv r=t||d	< n2|d
krN|du rGdnt||d
< n!|dkr_|du rXdnt||d< n|dkro|du ridnt||d< | | j	di |I dH  dS dS )a  Runtime updates via key/value pair.

        .. deprecated:: 0.0.104
            Use ``TTSUpdateSettingsFrame(delta=HumeTTSService.Settings(...))`` instead.

        Args:
            key: The name of the setting to update. Recognized keys are:
                - "voice_id"
                - "description"
                - "speed"
                - "trailing_silence"
            value: The new value for the setting.
        alwaysz_'update_setting' is deprecated, use 'TTSUpdateSettingsFrame(delta=self.Settings(...))' instead.   )
stacklevelN >   r'   r;   r4   r&   r(   )r4   r;   r;   r&   r'   r(   r!   )
warningscatch_warningssimplefilterwarnDeprecationWarninglowerr-   r/   _update_settingsrI   )rU   rk   rl   key_l
known_keysrV   r!   r!   r"   update_setting   s.   

	 zHumeTTSService.update_settingtext
context_idc              
   C  sb  t |  d| d |t| jjdd}| jjdur"| jj|d< | jjdur.| jj|d< | jjdur:| jj|d< tdi |}t	d	d
}| 
|I dH  zzd| _| jjdur[dnd}d}| jjj|g|d|dgd2 zj3 dH W }t|dd}	|	r|  I dH  t|	}
|  j|
7  _t| j| jkrt| j| jd|d}|V  d| _t|tr|j}|jdkr| j|jjd  }| j|jjd  }t||}|  |j!|fg|I dH  qm6 | jrt| j| jd|d}|V  d| _|dkr|| _W n  t"y } z| j#d| |dI dH  W Y d}~nd}~ww W |  I dH  dS W |  I dH  dS |  I dH  w )a  Generate speech from text using Hume TTS with word timestamps.

        Args:
            text: The text to be synthesized.
            context_id: Unique identifier for this TTS context.

        Returns:
            An async generator that yields `Frame` objects, including
            `TTSStartedFrame`, `TTSAudioRawFrame`, `ErrorFrame`, and
            `TTSStoppedFrame`.
        z: Generating Hume TTS: [])id)r{   r;   Nr&   r'   r(   pcm)typerB   12rC   Tword)
utterancesformatinstant_moder	   include_timestamp_typesaudio   )r   r6   num_channelsr|   g     @@r   zUnknown error occurred: )	error_msg	exceptionr!   )$r   debugr   r1   r;   r&   r'   r(   r   r   start_tts_usage_metricsrS   rR   ttssynthesize_json_streaminggetattrstop_ttfb_metricsbase64	b64decodelen
chunk_sizer   r6   ri   r   	timestampr   rT   timebeginendmaxrj   r{   	Exception
push_error)rU   r{   r|   utterance_kwargs	utterancepcm_fmtr	   utterance_durationchunk	audio_b64	pcm_bytesr\   r   word_start_timeword_end_timeer!   r!   r"   run_tts  s   





*&"zHumeTTSService.run_tts)!r)   r*   r+   r,   r   rI   r.   r   r2   rG   r   r-   intrM   boolr[   r   r]   r^   r   ra   r
   re   r   
DOWNSTREAMr   rh   r   rz   r   r   r   __classcell__r!   r!   rX   r"   r0   B   s@   
 	U	

&(r0   )5r,   r   rD   rq   dataclassesr   r   typingr   r   r   rN   logurur   pydanticr   r   r	   pipecat_versionpipecat.frames.framesr
   r   r   r   r   r   r   "pipecat.processors.frame_processorr   pipecat.services.settingsr   r   r   pipecat.services.tts_servicer   (pipecat.utils.tracing.service_decoratorsr   humer   hume.ttsr   r   r   hume.tts.typesr   ModuleNotFoundErrorr   errorr   rG   rP   r   r0   r!   r!   r!   r"   <module>   s@   $	
