o
    iU                     @  s  d dl mZ d dl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 d dlmZ d dlmZ d dl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 ddl m!Z!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,m-Z-m.Z. ddl*m/Z/m0Z0m1Z1m2Z2m3Z3 erddl4m5Z5 e6e7dd Z8eG dd dZ9eG dd dZ:G dd deZ;edZ<G dd deej=ed e<B  ee< Z>G dd  d eZ?G d!d" d"e?Z@G d#d$ d$eZAG d%d& d&ZBdS )'    )annotationsN)ABCabstractmethod)AsyncIterableAsyncIterator)	dataclass)TracebackType)TYPE_CHECKINGClassVarGenericLiteralTypeVar)trace)	BaseModel
ConfigDictField)rtc)Metadata   )APIErrorAPIStatusErrorlogger)
TTSMetrics)trace_typestracerutils)DEFAULT_API_CONNECT_OPTIONSUSERDATA_TIMED_TRANSCRIPTAPIConnectOptions)aioaudiocodecslog_exceptions	shortuuidTimedStringLK_DUMP_TTSc                   @  sJ   e Zd ZU ded< 	 ded< 	 dZded< 	 dZded	< 	 dZded
< dS )SynthesizedAudiortc.AudioFrameframestr
request_idFboolis_final 
segment_id
delta_textN)__name__
__module____qualname____annotations__r.   r0   r1    r6   r6   X/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/agents/tts/tts.pyr(       s   
 r(   c                   @  s$   e Zd ZU ded< 	 dZded< dS )TTSCapabilitiesr-   	streamingFaligned_transcriptN)r2   r3   r4   r5   r:   r6   r6   r6   r7   r8   .   s
   
 r8   c                   @  sP   e Zd ZU eddZdZded< ded< ded	< ed
ddZded< ded< dS )TTSErrorT)arbitrary_types_allowed	tts_errorzLiteral['tts_error']typefloat	timestampr+   label.)exclude	Exceptionerrorr-   recoverableN)	r2   r3   r4   r   model_configr>   r5   r   rD   r6   r6   r6   r7   r;   6   s   
 
r;   TEventc                      s   e Zd Zd1 fdd	Zed2ddZed2ddZed2ddZed3ddZed4ddZ	ed4ddZ
eedd5ddZedd6dd Zedd5d!d"Zd7d#d$Zd7d%d&Zd8d'd(Zd9d/d0Z  ZS ):TTScapabilitiesr8   sample_rateintnum_channelsreturnNonec                  s<   t    || _|| _|| _t| j dt| j | _d S )N.)	super__init___capabilities_sample_rate_num_channelsr>   r3   r2   _label)selfrI   rJ   rL   	__class__r6   r7   rQ   G   s
   
 zTTS.__init__r+   c                 C     | j S N)rU   rV   r6   r6   r7   rA   T      z	TTS.labelc                 C     dS )zGet the model name/identifier for this TTS instance.

        Returns:
            The model name if available, "unknown" otherwise.

        Note:
            Plugins should override this property to provide their model information.
        unknownr6   r[   r6   r6   r7   modelX      
z	TTS.modelc                 C  r]   )zGet the provider name/identifier for this TTS instance.

        Returns:
            The provider name if available, "unknown" otherwise.

        Note:
            Plugins should override this property to provide their provider information.
        r^   r6   r[   r6   r6   r7   providerd   r`   zTTS.providerc                 C  rY   rZ   )rR   r[   r6   r6   r7   rI   p   r\   zTTS.capabilitiesc                 C  rY   rZ   )rS   r[   r6   r6   r7   rJ   t   r\   zTTS.sample_ratec                 C  rY   rZ   )rT   r[   r6   r6   r7   rL   x   r\   zTTS.num_channelsconn_optionstextrc   r   ChunkedStreamc                C  s   d S rZ   r6   rV   rd   rc   r6   r6   r7   
synthesize|   s   zTTS.synthesizeSynthesizeStreamc                C  s   t d)NzYstreaming is not supported by this TTS, please use a different TTS or use a StreamAdapter)NotImplementedError)rV   rc   r6   r6   r7   stream   s   z
TTS.streamc                C  s   t | ||dS )a
  Helper method to implement synthesize() using stream() for TTS providers
        that only support streaming inference.

        This creates a stream, pushes the text as a single chunk, ends the input,
        and returns a ChunkedStream wrapper around it.
        tts
input_textrc   )_ChunkedStreamFromStreamrf   r6   r6   r7   _synthesize_with_stream   s
   	zTTS._synthesize_with_streamc                 C  r]   )z&Pre-warm connection to the TTS serviceNr6   r[   r6   r6   r7   prewarm   s   zTTS.prewarmc                      d S rZ   r6   r[   r6   r6   r7   aclose   s    z
TTS.aclosec                      | S rZ   r6   r[   r6   r6   r7   
__aenter__      zTTS.__aenter__exc_typetype[BaseException] | NoneexcBaseException | Noneexc_tbTracebackType | Nonec                      |   I d H  d S rZ   rr   rV   rv   rx   rz   r6   r6   r7   	__aexit__      zTTS.__aexit__)rI   r8   rJ   rK   rL   rK   rM   rN   rM   r+   )rM   r8   rM   rK   )rd   r+   rc   r   rM   re   )rc   r   rM   rh   rM   rN   )rM   rH   rv   rw   rx   ry   rz   r{   rM   rN   )r2   r3   r4   rQ   propertyrA   r_   ra   rI   rJ   rL   r   r   rg   rj   ro   rp   rr   rt   r   __classcell__r6   r6   rW   r7   rH   B   s2    


rH   )metrics_collectedrD   c                   @  s   e Zd ZU dZdZded< d;ddZed<ddZed=ddZ	ed>ddZ
d?ddZd@ddZedAd d!ZdBd"d#ZdCd'd(ZdBd)d*ZdDd,d-ZdEd/d0ZdFd1d2ZdGd8d9Zd:S )Hre   zVUsed by the non-streamed synthesize API, some providers support chunked http responsestts_requestClassVar[str]_tts_request_span_namerl   rH   rm   r+   rc   r   rM   rN   c                  s   | _ | _| _tjt   _tj jd _	 j	\ _
}d _tj |dd _d fdd}tj| d	d _ j fd
d d  _d S )Nr   FTTS._metrics_tasknamerM   rN   c                     F   t j jdd   I d H  W d    d S 1 sw   Y  d S NF)end_on_exitr   start_as_current_spanr   
_main_taskr6   r[   r6   r7   _traceable_main_task      "z4ChunkedStream.__init__.<locals>._traceable_main_taskzTTS._synthesize_taskc                   
    j  S rZ   	_event_chclose_r[   r6   r7   <lambda>      
 z(ChunkedStream.__init__.<locals>.<lambda>r   )_input_text_tts_conn_optionsr    Chanr(   r   	itertoolstee_tee_event_aiter_current_attempt_has_errorasynciocreate_task_metrics_monitor_task_metrics_task_synthesize_taskadd_done_callback_tts_request_span)rV   rl   rm   rc   monitor_aiterr   r6   r[   r7   rQ      s    

zChunkedStream.__init__c                 C  rY   rZ   )r   r[   r6   r6   r7   rm      r\   zChunkedStream.input_textr-   c                 C  
   | j  S rZ   )r   doner[   r6   r6   r7   r         
zChunkedStream.donery   c                 C  r   rZ   )r   	exceptionr[   r6   r6   r7   r      r   zChunkedStream.exceptionevent_aiterAsyncIterable[SynthesizedAudio]c           	        s   t  }d}d}d}|2 z3 dH W }|j}|dkr t  | }||jj7 }q6 t  | }| jr3dS tt   |||t| j|| j	
 | jjdt| jj| jjdd
}| jr`| jtj|  | jd| dS )	Task used to collect metrics              r/   NF
model_namemodel_provider)
r@   r,   ttfbdurationcharacters_countaudio_duration	cancelledrA   streamedmetadatar   )timeperf_counterr,   r*   r   r   r   lenr   r   r   r   rU   r   r_   ra   r   set_attributer   ATTR_TTS_METRICSmodel_dump_jsonemit)	rV   r   
start_timer   r   r,   evr   metricsr6   r6   r7   r      s>   
z#ChunkedStream._metrics_monitor_taskr)   c                   s0   g }| 2 z3 dH W }| |j q6 t|S )z6Utility method to collect every frame in a single callN)appendr*   r   combine_audio_frames)rV   framesr   r6   r6   r7   collect   s   
zChunkedStream.collectoutput_emitterAudioEmitterc                   rq   rZ   r6   rV   r   r6   r6   r7   _run  ru   zChunkedStream._runc                   s0  t   | _}|tjdtj| jji t	| j
jd D ]}t| jj| jd}zzltd-}|tj| z
| |I d H  W n tyT } zt||  d }~ww W d    n1 s_w   Y  |  | I d H  | j r| dkrtd| j |tj| j W W | I d H   d S  ty } zbt|tr|j dkrW Y d }~W | I d H   d S | j
!|}| j
jdks| j
j|kr| j"|dd	  | j"|d
d	 t#j$d| d| d| jj%|d ddd t&'|I d H  d| _(W Y d }~nd }~ww W | I d H  q| I d H  w d S )NF   rA   dst_chtts_request_runr   &no audio frames were pushed for text:   r   rE   Tfailed to synthesize speech: , retrying in srl   attemptr   extra))r   get_current_spanr   set_attributesr   ATTR_TTS_STREAMINGATTR_TTS_LABELr   rA   ranger   	max_retryr   r   r   r   r   ATTR_RETRY_COUNTr   rC   telemetry_utilsrecord_exception	end_inputjoinr   strippushed_durationr   ATTR_TTS_INPUT_TEXTrr   
isinstancer   status_code_interval_for_retry_emit_errorr   warningrU   r   sleepr   rV   current_spanir   attempt_spaneretry_intervalr6   r6   r7   r   	  s`   
 zChunkedStream._main_task	api_errorrC   rE   c              	   C  ,   d| _ | jdtt | jj||d d S NTrD   )r@   rA   rD   rE   r   r   r   r;   r   rU   rV   r   rE   r6   r6   r7   r   <     zChunkedStream._emit_errorc                   sX   t | jI dH  | j  | jI dH  | j I dH  | jr*| j	  d| _dS dS )zCClose is automatically called if the stream is completely collectedN)
r    cancel_and_waitr   r   r   r   r   rr   r   endr[   r6   r6   r7   rr   H  s   


zChunkedStream.acloser(   c                   J   z| j  I d H }W |S  ty$   | j s!| j  }r!|td w rZ   )r   	__anext__StopAsyncIterationr   r   r   rV   valrx   r6   r6   r7   r  R     zChunkedStream.__anext__AsyncIterator[SynthesizedAudio]c                 C     | S rZ   r6   r[   r6   r6   r7   	__aiter__]     zChunkedStream.__aiter__c                   rs   rZ   r6   r[   r6   r6   r7   rt   `  ru   zChunkedStream.__aenter__rv   rw   rx   rz   r{   c                   r|   rZ   r}   r~   r6   r6   r7   r   c  r   zChunkedStream.__aexit__Nrl   rH   rm   r+   rc   r   rM   rN   r   )rM   r-   )rM   ry   r   r   rM   rN   )rM   r)   r   r   rM   rN   r   r   rC   rE   r-   rM   rN   rM   r(   rM   r
  )rM   re   r   )r2   r3   r4   __doc__r   r5   rQ   r   rm   r   r   r   r   r   r   r   r   rr   r  r  rt   r   r6   r6   r6   r7   re      s*   
 


&

3




re   c                      s,   e Zd ZdZd fd
dZdddZ  ZS )rn   zImplementation of ChunkedStream that wraps a SynthesizeStream.

    Used by TTS providers that only support streaming inference to implement
    the synthesize() method.
    rl   rH   rm   r+   rc   r   rM   rN   c                  s   t  j|||d d S )Nrk   )rP   rQ   )rV   rl   rm   rc   rW   r6   r7   rQ   s  s
   
z!_ChunkedStreamFromStream.__init__r   r   c              	     s   |j t | jj| jjddd | jjtd| jjdd4 I d H 6}|	| j
 |  |2 z3 d H W }||jj  |jjt }rK|| q.6 W d   I d H  n1 I d H s]w   Y  |  d S )N	audio/pcmF)r,   rJ   rL   	mime_typerj   r   )r   timeoutrb   )
initializer$   r   rJ   rL   rj   r   r   r  	push_textr   r   pushr*   datatobytesuserdatagetr   push_timed_transcriptflush)rV   r   rj   r   timed_transcriptsr6   r6   r7   r     s,   
(
z_ChunkedStreamFromStream._runr  r  )r2   r3   r4   r  rQ   r   r   r6   r6   rW   r7   rn   l  s    rn   c                      s   e Zd ZU dZded< G dd dZd: fddZed;ddZd<ddZ	d=ddZ
d<ddZd>ddZd?d"d#Zd<d$d%Zd<d&d'Zd<d(d)Zd@d+d,ZdAd.d/ZdBd0d1ZdCd8d9Z  ZS )Drh   r   r   r   c                   @     e Zd ZdS )zSynthesizeStream._FlushSentinelNr2   r3   r4   r6   r6   r6   r7   _FlushSentinel  s    r$  rl   rH   rc   r   rM   rN   c                  s   t    | _| _tjttjB    _	tjt
   _tj jd _ j\ _ _d fdd}tj| dd _ j fdd	 d  _d
 _d _d _g  _d _d _d  _d S )Nr   rM   rN   c                     r   r   r   r6   r[   r6   r7   r     r   z7SynthesizeStream.__init__.<locals>._traceable_main_taskzTTS._main_taskr   c                   r   rZ   r   r   r[   r6   r7   r     r   z+SynthesizeStream.__init__.<locals>.<lambda>Fr   r/   r   )rP   rQ   r   r   r    r   r+   rh   r$  	_input_chr(   r   r   r   r   r   _monitor_aiterr   r   _taskr   r   r   _started_time_pushed_text_mtc_pending_texts	_mtc_text_num_segmentsr   )rV   rl   rc   r   rW   r[   r7   rQ     s$   

zSynthesizeStream.__init__r   r   c                   rq   rZ   r6   r   r6   r6   r7   r     ru   zSynthesizeStream._runc                   sZ  t   | _}|tjdtj| jji t	| j
jd D ]}t| jj| jd}zztd-}|tj| z
| |I d H  W n tyU } zt||  d }~ww W d    n1 s`w   Y  |  | I d H  | j r|jdddkrtd| j | j|jkrtd	| j d
|j |tj| j W W | I d H   d S  ty } zbt |t!r|j"dkrW Y d }~W | I d H   d S | j
#|}| j
jdks| j
j|kr| j$|dd  | j$|dd t%j&d| d| d| jj'|d ddd t()|I d H  d| _*W Y d }~nd }~ww W | I d H  q| I d H  w d S )NTr   r   r   )idxr   r   z&number of segments mismatch: expected z
, but got r   r   Fr   r   r   r   r   r   )+r   r   r   r   r   r   r   r   rA   r   r   r   r   r   r   r   r   r   r   rC   r   r   r   r   r)  r   r   r   r,  num_segmentsr   rr   r   r   r   r   r   r   r   rU   r   r   r   r   r6   r6   r7   r     sn   


 zSynthesizeStream._main_taskr   rC   rE   r-   c              	   C  r   r   r   r   r6   r6   r7   r     r  zSynthesizeStream._emit_errorc                 C  s   | j dkrt | _ d S d S )Nr   )r(  r   r   r[   r6   r6   r7   _mark_started  s   
zSynthesizeStream._mark_startedr   r   c                   sz   d dddd	 fdd}|2 z#3 dH W }dkr't  j  |jj7  |j|j|jr9|  q6 dS )
r   r   r   r/   rM   rN   c                    s   j rjrd S t j  } jsd S jd}|sd S tt | t| j	 j
jdtj
jj
jdd}jrKjtj|  j
d| d ddd_ d S )	Nr   Tr   )r@   r,   r0   r   r   r   r   r   rA   r   r   r   r   r   r/   )r(  r   r   r   r*  popr   r   r'  r   r   rU   r   r_   ra   r   r   r   r   r   r   )r   rd   r   r   r,   r0   rV   r   r6   r7   _emit_metrics
  s<   

z=SynthesizeStream._metrics_monitor_task.<locals>._emit_metricsNr   )r   r   r(  r*   r   r,   r0   r.   )rV   r   r3  r   r6   r2  r7   r     s    'z&SynthesizeStream._metrics_monitor_tasktokenr+   c                 C  s   |r| j jrdS |  j|7  _| jdu r tj| | jdd| _| js6| j	dkr/t
d dS |  j	d7  _	|  j|7  _| j | dS )z Push some text to be synthesizedNr   r   r   zSynthesizeStream: handling multiple segments in a single instance is deprecated. Please create a new SynthesizeStream instance for each segment. Most TTS plugins now use pooled WebSocket connections via ConnectionPool.)r%  closedr)  r   r   r   r   r&  r+  r,  r   r   send_nowait)rV   r4  r6   r6   r7   r  <  s    

zSynthesizeStream.push_textc                 C  s:   | j jrdS | jr| j| j d| _| j |   dS )z#Mark the end of the current segmentNr/   )r%  r5  r+  r*  r   r6  r$  r[   r6   r6   r7   r   V  s   zSynthesizeStream.flushc                 C  s   |    | j  dS )z2Mark the end of input, no more text will be pushedN)r   r%  r   r[   r6   r6   r7   r   a  s   zSynthesizeStream.end_inputc                   sl   t | jI dH  | j  | j  | jdur| jI dH  | j I dH  | j	r4| j	
  d| _	dS dS )zClose ths stream immediatelyN)r    r  r'  r   r   r%  r   r   rr   r   r  r[   r6   r6   r7   rr   f  s   




zSynthesizeStream.acloser(   c                   r  rZ   )r   r  r  r'  r   r   r  r6   r6   r7   r  u  r	  zSynthesizeStream.__anext__r
  c                 C  r  rZ   r6   r[   r6   r6   r7   r    r  zSynthesizeStream.__aiter__c                   rs   rZ   r6   r[   r6   r6   r7   rt     ru   zSynthesizeStream.__aenter__rv   rw   rx   ry   rz   r{   c                   r|   rZ   r}   r~   r6   r6   r7   r     r   zSynthesizeStream.__aexit__)rl   rH   rc   r   rM   rN   r  r   r  r  )r4  r+   rM   rN   r  r  )rM   rh   r   )r2   r3   r4   r   r5   r$  rQ   r   r   r   r   r0  r   r  r   r   rr   r  r  rt   r   r   r6   r6   rW   r7   rh     s$   
 

:


9





rh   c                   @  s   e Zd ZG dd dZeG dd dZG dd dZeG dd dZdBddZdCdDddZ	e
dEddZddddFd#d$ZdGd&d'ZdGd(d)ZdHd*d+ZdHd,d-ZdId0d1ZdJd4d5ZdHd6d7ZdHd8d9ZdHd:d;ZdHd<d=Zeed>dHd?d@ZdAS )Kr   c                   @  r"  )zAudioEmitter._FlushSegmentNr#  r6   r6   r6   r7   _FlushSegment      r7  c                   @  s   e Zd ZU ded< dS )zAudioEmitter._StartSegmentr+   r0   N)r2   r3   r4   r5   r6   r6   r6   r7   _StartSegment  s   
 r9  c                   @  r"  )zAudioEmitter._EndSegmentNr#  r6   r6   r6   r7   _EndSegment  r8  r:  c                   @  s"   e Zd ZU ded< dZded< dS )zAudioEmitter._SegmentContextr+   r0   r   r?   r   N)r2   r3   r4   r5   r   r6   r6   r6   r7   _SegmentContext  s   
 r;  rA   r+   r   aio.Chan[SynthesizedAudio]rM   rN   c                C  s(   || _ || _d| _d| _d| _g | _d S )Nr/   Fr   )_dst_chrU   _request_id_startedr,  _audio_durations)rV   rA   r   r6   r6   r7   rQ     s   
zAudioEmitter.__init__r-  r.  rK   r?   c                 C  s4   t | j |  krt | jk rn n| j| S dS )Nr   )r   r@  )rV   r.  r6   r6   r7   r     s
   &zAudioEmitter.pushed_durationc                 C  rY   rZ   )r,  r[   r6   r6   r7   r/    r\   zAudioEmitter.num_segments   F)frame_size_msrj   r,   rJ   rL   r  rB  rj   r-   c          	      C  s   | j rtdd| _|r|  }|dp|d| _|| _|s+td| j	 d}d| _ || _
|| _|| _|| _|| _dd	lm} tjttjB tjB tjB |B   | _tj|  d
d| _| jsj| jdd d S d S )NzAudioEmitter already startedFr  z	audio/rawz!no request_id provided for TTS %sr^   Tr   r%   AudioEmitter._main_taskr   r/   r0   )r?  RuntimeError_is_raw_pcmlowerr   
startswith
_mime_typer   r   rU   r>  _frame_size_msrS   rT   
_streamingvoice.ior&   r    r   bytesr   r7  r9  r:  	_write_chr   r   r   _main_atask_AudioEmitter__start_segment)	rV   r,   rJ   rL   r  rB  rj   mtr&   r6   r6   r7   r    s@   
zAudioEmitter.initializer0   c                C  s   | j std| j|dS )NzXstart_segment() can only be called when SynthesizeStream is initialized with stream=TruerD  )rK  rE  rP  rV   r0   r6   r6   r7   start_segment  s
   zAudioEmitter.start_segmentc                C  s@   | j std| jjrd S |  jd7  _| j| j|d d S )NAudioEmitter isn't startedr   rD  )r?  rE  rN  r5  r,  r6  r9  rR  r6   r6   r7   __start_segment  s   zAudioEmitter.__start_segmentc                 C  s   | j std|  S )NzVend_segment() can only be called when SynthesizeStream is initialized with stream=True)rK  rE  _AudioEmitter__end_segmentr[   r6   r6   r7   end_segment  s
   zAudioEmitter.end_segmentc                 C  .   | j std| jjrd S | j|   d S NrT  )r?  rE  rN  r5  r6  r:  r[   r6   r6   r7   __end_segment   
   zAudioEmitter.__end_segmentr  rM  c                 C  s*   | j std| jjrd S | j| d S rY  )r?  rE  rN  r5  r6  )rV   r  r6   r6   r7   r  	  s
   zAudioEmitter.pushr1   TimedString | list[TimedString]c                 C  sN   | j std| jjrd S t|tr|D ]}| j| qd S | j| d S rY  )r?  rE  rN  r5  r   listr6  )rV   r1   rd   r6   r6   r7   r    s   
z"AudioEmitter.push_timed_transcriptc                 C  rX  rY  )r?  rE  rN  r5  r6  r7  r[   r6   r6   r7   r     r[  zAudioEmitter.flushc                 C  s0   | j std| jjrd S |   | j  d S rY  )r?  rE  rN  r5  rV  r   r[   r6   r6   r7   r   (  s   zAudioEmitter.end_inputc                   s    | j std| jI d H  d S rY  )r?  rE  rO  r[   r6   r6   r7   r   2  s   zAudioEmitter.joinc                   s"   | j sd S t| jI d H  d S rZ   )r?  r    r  rO  r[   r6   r6   r7   rr   8  s   zAudioEmitter.acloser   c           	   
     s  ddl m} d d }d d g g d d 
d	t ddd#	
fddd$ddd%fdd d&	
f	dd}d&fdd}ttdd& fdd}d }zBj2 z3 d H W }t||r{| qit|t	j
rrtdjd t	j|jdqisjrt|t	jt	jfrqitdjrt|tr|d u rtjjjtjd j d}||D ]} | qqi|rt|t	jr| D ]} | q|  qit|t	jr| D ]} | q d d |  d   }qitd!t| qit|tr6s0tjjjj d"t!| }| qi|rt|t	jrRrQ"  |I d H  |  d qit|t	jryryrh"  |I d H   d d |  d    }qitd!t| qi6 W d ur#  r|r$ I d H  t%&|I d H  d S d S d S d ur#  r|rȈ$ I d H  t%&|I d H  w w w )'Nr   r%   r   Fflush_if_delayedr   r(   r_  r-   rM   rN   c                  sr   j |  d u r  | jj7 d ur  dfdd}|r7    d } ||d S d S )NrM   rN   c                     s       td d S )Nz0flush audio emitter due to slow audio generation)r   r   debugr6   r[   r6   r7   _flushY  s   z<AudioEmitter._main_task.<locals>._send_audio.<locals>._flushg{Gz?r   )r=  r6  r   r*   r   cancel
call_later)r   r_  ra  delay)
event_loopflush_timerrV   sent_duration
sent_startr6   r7   _send_audioN  s   z,AudioEmitter._main_task.<locals>._send_audio)r.   r*   rtc.AudioFrame | Noner.   c                  s.  d usJ d u r`|s| d S j dkr`| d u r0tjdjd j  jjjd d} n j | j7  _ jd  | j7  < trI|  | j	t
<  t| jjdddd	 g d S d urj	t
<  tjj|d| d	 g  j j7  _ jd  j7  < tr | d S )
Nr   s     d   )r  rJ   rL   samples_per_channelr-  Tr*   r,   r0   r.   Fr^  )r   r   
AudioFramerS   rT   r   r@  lk_dump_ttsr   r  r   r(   r>  r0   )r*   r.   )ri  debug_frames
last_framesegment_ctxrV   r!  r6   r7   _emit_frameb  s\   


	
	
z,AudioEmitter._main_task.<locals>._emit_framec                     s   d usJ d u rd S j t<  tjjdddd g  jj7  _jd  j7  < tr:	 d d dd urL
  d d S d S )NFrm  r^  r-  r   )r  r   r(   r>  r0   r   r   r@  ro  r   rb  r6   )	ri  rp  rf  rq  rr  rV   rg  rh  r!  r6   r7   _flush_frame  s2   
	
z-AudioEmitter._main_task.<locals>._flush_framec               	     s   d usJ t r
 sd S tj d} jr)dj dj dj d|  d	ndj dj d|  d}t|d}|	t
   W d    n1 sQw   Y     d S )Nz%Y-%m-%d_%H-%M-%Szlk_dump/r   z.wavwb)ro  datetimenowstrftimerK  rU   r>  r0   openwriter   r   to_wav_bytesclear)tsfnamef)rp  rr  rV   r6   r7   dump_segment  s   &z-AudioEmitter._main_task.<locals>.dump_segmentr   c                    s   d usJ d usJ d } 2 z)3 d H W }| d u r-t j|j|jt|jd j d} | |jD ]} | q3q6 | rI|  D ]} | qB	 I d H  d S )N  rJ   rL   rl  )
r!   AudioByteStreamrJ   rL   rK   rJ  r  r  r   rr   )audio_byte_streamr*   r  )rs  audio_decoderrr  rV   r6   r7   _decode_task  s&   


z-AudioEmitter._main_task.<locals>._decode_taskz<start_segment() called before the previous segment was endedrD  z8start_segment() must be called before pushing audio datar  r  Tzunknown data type: %s)rJ   rL   format)r   r(   r_  r-   rM   rN   rZ   )r*   rj  r.   r-   rM   rN   r   )'rL  r&   r   get_event_loopr#   r   rN  r   r   r   r9  rE  r@  r;  r0   rK  r:  r7  rF  rM  r!   r  rS   rT   rK   rJ  r  r   r   r>   r"   AudioStreamDecoderrI  r   r   rb  rr   r    r  )	rV   r&   decode_ataskrt  r  r  r  r  r  r6   )rs  ri  r  rp  re  rf  rq  rr  rV   rg  rh  r!  r7   r   >  s    :!










Q
rC  N)rA   r+   r   r<  rM   rN   )r-  )r.  rK   rM   r?   r   )r,   r+   rJ   rK   rL   rK   r  r+   rB  rK   rj   r-   rM   rN   )r0   r+   rM   rN   r   )r  rM  rM   rN   )r1   r\  rM   rN   )r2   r3   r4   r7  r   r9  r:  r;  rQ   r   r   r/  r  rS  rP  rW  rV  r  r  r   r   r   rr   r#   r   r   r6   r6   r6   r7   r     s4    


-
	


	
	
	

	


r   )C
__future__r   r   rv  osr   abcr   r   collections.abcr   r   dataclassesr   typesr   typingr	   r
   r   r   r   opentelemetryr   pydanticr   r   r   livekitr   livekit.agents.metrics.baser   _exceptionsr   r   logr   r   r   	telemetryr   r   r   r   r   r   r   r    r!   r"   r#   r$   rL  r&   rK   getenvro  r(   r8   r;   rG   EventEmitterrH   re   rn   rh   r   r6   r6   r6   r7   <module>   sP    	
g D) {