
    qix8                        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 m!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+ ddl,m-Z- dZ2d e       dZ3e G d de             Z4 G d de#      Z5y# e.$ r7Z/ ej`                  de/         ej`                  d        e1de/       dZ/[/ww xY w)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_warn_deprecated_param)
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                       e Zd ZU dZ ed       Zedz  ez  ed<    ed       Z	e
dz  ez  ed<    ed       Ze
dz  ez  ed	<   y)
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                      t         S Nr        K/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/hume/tts.py<lambda>zHumeTTSSettings.<lambda>=   s    	 r%   )default_factoryNdescriptionc                      t         S r"   r#   r$   r%   r&   r'   zHumeTTSSettings.<lambda>>   s    I r%   speedc                      t         S r"   r#   r$   r%   r&   r'   zHumeTTSSettings.<lambda>?   s    y r%   trailing_silence)__name__
__module____qualname____doc__r   r)   strr   __annotations__r+   floatr-   r$   r%   r&   r    r    3   sU     +0@Q*RKti'R&+<M&NE54<)#N16GX1YedlY.Yr%   r    c                   D    e Zd ZU dZeZeed<    G 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ZdefdZdeddf fdZd Zdeddf fdZdeddf fdZej0                  fdedef fdZdededdfdZedededeedf   fd       Z x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                   N    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<   y)HumeTTSService.InputParamsa}  Optional synthesis parameters for Hume TTS.

        .. deprecated:: 0.0.105
            Use ``settings=HumeTTSSettings(...)`` 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/   r0   r1   r)   r   r2   r3   r+   r4   r-   r$   r%   r&   InputParamsr9   T   s4    		 &*Xc])!%x%,0(5/0r%   r:   N)api_keyvoice_idparamssample_ratesettingsr;   r<   r=   r>   r?   returnc          	      h   |xs t        j                  d      }|st        d      |t        k7  rt	        j
                  dt         d|        t        dddddd      }|t        dt        d       ||_        |Et        d	t               |s3|j                  |_	        |j                  |_
        |j                  |_        ||j                  |       t        | 8  d|d
dd|d| t        j                   t"              | _        t'        || j$                        | _        d| _        d| _        y)as  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=HumeTTSSettings(voice=...)`` instead.

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

                .. deprecated:: 0.0.105
                    Use ``settings=HumeTTSSettings(...)`` 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-   r<   rD   r=   FT)r>   push_text_framespush_stop_framespush_start_framer?   )headers)r;   httpx_clientr%           r$   )osgetenv
ValueErrorHUME_SAMPLE_RATEr   warningr    r   rD   r)   r+   r-   apply_updatesuper__init__httpxAsyncClientDEFAULT_HEADERS_http_clientr   _client_audio_bytes_cumulative_time)	selfr;   r<   r=   r>   r?   kwargsdefault_settings	__class__s	           r&   rS   zHumeTTSService.__init__d   sI   : 6RYY~6`aa**NN&'7&88TU`Tab
 +!
 ":H%-" "8_=/5/A/A ,)/ &4:4K4K 1 ))(3 	
#"!!%	
 	
 "--oF&wTEVEVW !$r%   c                      y)zoCan generate metrics.

        Returns:
            True if metrics can be generated, False otherwise.
        Tr$   r[   s    r&   can_generate_metricsz#HumeTTSService.can_generate_metrics   s     r%   framec                 `   K   t         |   |       d{    | j                          y7 w)zNStart the service.

        Args:
            frame: The start frame.
        N)rR   start_reset_stater[   rb   r^   s     r&   rd   zHumeTTSService.start   s,      gmE""" 	#s   .,.c                     d| _         y)zReset internal state variables.rK   N)rZ   r`   s    r&   re   zHumeTTSService._reset_state   s
     #r%   c                    K   t         |   |       d{    t        | d      r0| j                  r#| j                  j	                          d{    yyy7 A7 	w)zaStop the service and cleanup resources.

        Args:
            frame: The end frame.
        NrW   )rR   stophasattrrW   acloserf   s     r&   ri   zHumeTTSService.stop   sV      gl5!!!4(T->->##**,,, .?( 	",!   AA9AAAAc                    K   t         |   |       d{    t        | d      r0| j                  r#| j                  j	                          d{    yyy7 A7 	w)zfCancel the service and cleanup resources.

        Args:
            frame: The cancel frame.
        NrW   )rR   cancelrj   rW   rk   rf   s     r&   rn   zHumeTTSService.cancel   sV      gnU###4(T->->##**,,, .?( 	$,rl   	directionc                    K   t         |   ||       d{    t        |t        t        f      r<| j                          t        |t              r| j                  dg       d{    yyy7 W7 	w)zPush a frame and handle state changes.

        Args:
            frame: The frame to push.
            direction: The direction to push the frame.
        N)Resetr   )rR   
push_frame
isinstancer   r   re   add_word_timestamps)r[   rb   ro   r^   s      r&   rr   zHumeTTSService.push_frame   sp      g 	222e/AB%1..~>>> 2	 C 	3 ?s"   A3A/AA3'A1(A31A3keyvaluec                   K   t        j                         5  t        j                  d       t        j                  dt        d       ddd       |xs dj                         }h d}||v ri }|dv rt        |      |d	<   nG|d
k(  r|dn
t        |      |d
<   n/|dk(  r|dn
t        |      |d<   n|dk(  r|dn
t        |      |d<   | j                  t        di |       d{    yy# 1 sw Y   xY w7 w)a  Runtime updates via key/value pair.

        .. deprecated:: 0.0.104
            Use ``TTSUpdateSettingsFrame(delta=HumeTTSSettings(...))`` 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.
        alwaysza'update_setting' is deprecated, use 'TTSUpdateSettingsFrame(delta=HumeTTSSettings(...))' instead.   )
stacklevelN >   r+   rD   r<   r)   r-   )r<   rD   rD   r)   r+   r-   r$   )
warningscatch_warningssimplefilterwarnDeprecationWarninglowerr2   r4   _update_settingsr    )r[   ru   rv   key_l
known_keysr\   s         r&   update_settingzHumeTTSService.update_setting   s     $$& 	!!(+MMP"		 !!#V
J%'F--"%e*w-'053u:}%'!*/-$U5\w,,5:]Te)*''(A&(ABBB 	 	, Cs)   C;2C-	BC;&C9'C;-C62C;text
context_idc                  K   t        j                  |  d| d       |t        | j                  j                        d}| j                  j
                  | j                  j
                  |d<   | j                  j                  | j                  j                  |d<   | j                  j                  | j                  j                  |d<   t        di |}t        d	
      }| j                  |       d{    	 d| _        | j                  j
                  dnd}d}| j                  j                  j                  |g|d|dg      2 3 d{   }t        |dd      }	|	r| j!                          d{    t#        j$                  |	      }
| xj                  |
z  c_        t'        | j                        | j(                  k\  r/t+        | j                  | j,                  d|      }| d| _        t/        |t0              s|j2                  }|j4                  dk(  s| j6                  |j8                  j:                  dz  z   }| j6                  |j8                  j<                  dz  z   }t?        ||      }| jA                  |jB                  |fg|       d{    Y7 7 X7 47 6 | j                  r/t+        | j                  | j,                  d|      }| d| _        |dkD  r|| _        n5# tD        $ r)}| jG                  d| |       d{  7   Y d}~nd}~ww xY w| j!                          d{  7   y# | j!                          d{  7   w xY w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   rD   Nr)   r+   r-   pcm)typer%   12rK   Tword)
utterancesformatinstant_moder
   include_timestamp_typesaudio   )r   r>   num_channelsr   g     @@r   zUnknown error occurred: )	error_msg	exceptionr$   )$r   debugr   r7   rD   r)   r+   r-   r   r   start_tts_usage_metricsrY   rX   ttssynthesize_json_streaminggetattrstop_ttfb_metricsbase64	b64decodelen
chunk_sizer   r>   rs   r   	timestampr   rZ   timebeginendmaxrt   r   	Exception
push_error)r[   r   r   utterance_kwargs	utterancepcm_fmtr
   utterance_durationchunk	audio_b64	pcm_bytesrb   r   word_start_timeword_end_timees                   r&   run_ttszHumeTTSService.run_tts  s@     	v5dV1=> /4>>3G3GH,
 >>%%1.2nn.H.H]+>>+(,(<(<W%>>**637>>3R3R/0#7&67	 '**4000K	+ !$D "^^77CcG "%#||//II%;!)/  J   ' 'e $E7D9	00222 & 0 0 ;I%%2% 4,,-@ 0"&"3"3(,(8(8)*'1	! $,/) e%56 %I ~~/*.*?*?9>>CWCWZ`C`*a(,(=(=ASASV\A\(] .11C]-S* #66'nno>?  i 	1' 36K T   (++ $ 0 0!")	 $'! "A%(:% 	Y//.Fqc,JVW/XXX	Y ((***$((***s   C7M(9J':M(?AK; J2J*J2#K; 9J-:BK; 
K; &A:K;  J0!K; 'M(*J2-K; 0K; 2AK; :M
 ;	L-L(L L(#M
 (L--M
 0M(MM(
M%M!M%%M()!r.   r/   r0   r1   r    Settingsr3   r	   r:   rO   r   r2   intrS   boolra   r   rd   re   r   ri   r   rn   r   
DOWNSTREAMr   rr   r   r   r   r   r   __classcell__)r^   s   @r&   r6   r6   B   sR    H1i 1& "&"&(,%5.2S$ #S$ 3-	S$
 %S$ c]S$ ?+S$ 
S$jd   $- -T --+ -$ - JXIbIb ?e ? ?$C $CC $CD $CL l+# l+3 l+>%QU+;V l+ l+r%   r6   )6r1   r   rL   r|   dataclassesr   r   typingr   r   r   rT   logurur   pydanticr	   r   r
   pipecat_versionpipecat.frames.framesr   r   r   r   r   r   r   "pipecat.processors.frame_processorr   pipecat.services.settingsr   r   r   r   pipecat.services.tts_servicer   (pipecat.utils.tracing.service_decoratorsr   humer   hume.ttsr   r   r   hume.tts.typesr   ModuleNotFoundErrorr   errorr   rO   rV   r    r6   r$   r%   r&   <module>r      s   
 2  	  ( 0 0    .   > _ _ 3 ?,$OO/   $,. Zk Z ZB+Z B+=  ,FLL;qc"#FLLTU
&qc*
++,s   (B& &C"+2CC"