o
    i?_                     @  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 d dlm	Z	m
Z
 d dlZd dlmZ ddlmZ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 dZe	G dd dZe	G dd dZe	G dd dZe	G dd dZ G dd dZ!G dd dZ"G dd dej#Z$G dd dej%Z&dS )     )annotationsN)Callable)	dataclassfield)rtc   )tokenizeutilslogger)	NOT_GIVEN
NotGivenOr)is_given   )io   )SpeakingRateDetectorSpeakingRateStreamgp=
ף@c                   @  s.   e Zd ZU ded< ded< ded< ded< d	S )
_TextSyncOptionsfloatspeedCallable[[str], list[str]]hyphenate_wordztokenize.WordTokenizerword_tokenizerr   speaking_rate_detectorN)__name__
__module____qualname____annotations__ r   r   q/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/agents/voice/transcription/synchronizer.pyr      s
   
 r   c                   @  s   e Zd ZU eedZded< 	 eedZded< 	 eedZded< 	 eedZ	ded< dddZ
dddZdddZedddZdS )_SpeakingRateDatadefault_factoryzlist[float]
timestampsspeaking_ratespeak_integrals	list[str]_text_buffer	timestampr   returnNonec                C  sR   | j r| jd nd}|| j }||| 7 }| j | | j| | j| d S Nr   )r$   r&   pushed_durationappendr%   )selfr)   r%   integraldtr   r   r    add_by_rate-   s   
z_SpeakingRateData.add_by_ratetextstr
start_timefloat | Noneend_timec                C  s   |d urB| j r| jd nd}|| j }tdd | jD }||7 }|dkr)|| nd}| j | | j| | j| | j  | j| |d urV| jd|d d d S d S )Nr-   r   c                 s  s    | ]}t |V  qd S N)len).0r4   r   r   r    	<genexpr>C   s    z6_SpeakingRateData.add_by_annotation.<locals>.<genexpr> r4   r6   r8   )	r$   r&   r.   sumr(   r/   r%   clearadd_by_annotation)r0   r4   r6   r8   r1   r2   text_lenrater   r   r    rA   6   s   

z#_SpeakingRateData.add_by_annotationc                 C  s   | j sdS tj| j |dd}|dkrdS | j|d  }|| j |d   }|t| jk r0| j| n| j|d  }||| 7 }|t| j k rLt|| j| }|S )z9Get accumulated speaking units up to the given timestamp.r   right)sider   )r$   npsearchsortedr&   r:   r%   min)r0   r)   idx
integral_tr2   rC   r   r   r    accumulate_toQ   s   
z_SpeakingRateData.accumulate_toc                 C  s   | j r| j d S dS r,   )r$   r0   r   r   r    r.   k   s   z!_SpeakingRateData.pushed_durationN)r)   r   r%   r   r*   r+   )r4   r5   r6   r7   r8   r7   r*   r+   )r)   r   r*   r   )r*   r   )r   r   r   r   listr$   r   r%   r&   r(   r3   rA   rK   propertyr.   r   r   r   r    r!       s   
 

	
r!   c                   @  sL   e Zd ZU ded< dZded< dZded< eed	Zd
ed< dZ	ded< dS )
_AudioDatar   	sr_stream        r   r.   Fbooldoner"   r!   estimated_rateNz_SpeakingRateData | Noneannotated_rate)
r   r   r   r   r.   rS   r   r!   rT   rU   r   r   r   r    rO   p   s   
 rO   c                   @  sF   e Zd ZU ded< dZded< dZded< d	Zd
ed< dZded< dS )	_TextDataztokenize.WordStreamword_streamr=   r5   pushed_textFrR   rS   r   intforwarded_hyphensforwarded_textN)r   r   r   r   rX   rS   rZ   r[   r   r   r   r    rV   y   s   
 rV   c                   @  s  e Zd ZdZ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
d>ddZd=ddZd=ddZd=dd Zd=d!d"Zd?d&d'Zed@d(d)Zejed*d=d+d,Zejed*d=d-d.Zejed*d=d/d0ZdAd2d3ZdBd5d6Zd=d7d8Zd9S )C_SegmentSynchronizerImplz4Synchronizes one text segment with one audio segmentoptionsr   next_in_chainio.TextOutput | Noner*   r+   c                  s   | _ t j j d _t j j d _| _d  _	t
  _d  _d _t
  _ j  t j j  _d  _tjjt   _t
jd    _t
   _ j fdd t
    _!t
 "  _#d _$d _%d S )N)rW   )rP   rQ   c                   s
    j  S r9   )_out_chclose)_rL   r   r    <lambda>   s   
 z3_SegmentSynchronizerImpl.__init__.<locals>.<lambda>F)&_optsrV   r   stream
_text_datarO   r   _audio_data_next_in_chain_start_wall_timeasyncioEvent
_start_fut_paused_wall_time_paused_duration_output_enabled_evsetSTANDARD_SPEECH_RATEr   _speed_speed_on_speaking_unitr	   aioChanr5   r`   Future_close_futurecreate_task
_main_task_main_ataskadd_done_callback_capture_task_capture_atask_speaking_rate_task_speaking_rate_atask_playback_completed_interrupted)r0   r]   r^   r   rL   r    __init__   s(   



z!_SegmentSynchronizerImpl.__init__rR   c                 C  s
   | j  S r9   )rw   rS   rL   r   r   r    closed   s   
z_SegmentSynchronizerImpl.closedc                 C     | j jS r9   )rg   rS   rL   r   r   r    audio_input_ended      z*_SegmentSynchronizerImpl.audio_input_endedc                 C  r   r9   )rf   rS   rL   r   r   r    text_input_ended   r   z)_SegmentSynchronizerImpl.text_input_endedframertc.AudioFramec                 C  s`   | j r
td d S | jd u r|jdkrt | _| j  | jj	
| | j j|j7  _d S )Nz6_SegmentSynchronizerImpl.push_audio called after closer   )r   r   warningri   durationtimerl   rp   rg   rP   
push_framer.   r0   r   r   r   r    
push_audio   s   


z#_SegmentSynchronizerImpl.push_audioc                 C  4   | j r
td d S d| j_| jj  |   d S )Nz;_SegmentSynchronizerImpl.end_audio_input called after closeT)r   r   r   rg   rS   rP   	end_input_reestimate_speedrL   r   r   r    end_audio_input   s   
z(_SegmentSynchronizerImpl.end_audio_inputr4   r5   c                 C  s   | j r
td d S d\}}t|tjr=t|jr|jnd }t|j	r(|j	nd }| j
js3t | j
_| j
jj|||d | jj| | j j|7  _d S )Nz5_SegmentSynchronizerImpl.push_text called after close)NNr>   )r   r   r   
isinstancer   TimedStringr	   r   r6   r8   rg   rU   r!   rA   rf   rW   	push_textrX   )r0   r4   r6   r8   r   r   r    r      s   

z"_SegmentSynchronizerImpl.push_textc                 C  r   )Nz:_SegmentSynchronizerImpl.end_text_input called after closeT)r   r   r   rf   rS   rW   r   r   rL   r   r   r    end_text_input   s   
z'_SegmentSynchronizerImpl.end_text_inputc                 C  s6   | j r
td d S | jd u rt | _| j  d S )Nz1_SegmentSynchronizerImpl.pause called after close)r   r   r   rm   r   ro   r@   rL   r   r   r    pause   s   


z_SegmentSynchronizerImpl.pausec                 C  s\   | j r
td d S | jd ur'| jd ur$|  jt t| j| j 7  _d | _| j	  d S )Nz2_SegmentSynchronizerImpl.resume called after close)
r   r   r   rm   ri   rn   r   maxro   rp   rL   r   r   r    resume   s   



z_SegmentSynchronizerImpl.resumec                 C  sl   | j jr| jjs
d S t| | j j}| jjdkr || jj | _| jj	| jj}|dkr4|| | _
d S d S )Nr   )rf   rS   rg   r:   _calc_hyphensrX   r.   rr   rT   rK   rs   )r0   pushed_hyphenspushed_speaking_unitsr   r   r    r      s   z*_SegmentSynchronizerImpl._reestimate_speedplayback_positionr   interruptedc                C  s\   | j r
td d S || _| jjr| jjs%tjd| jj| jjdd d S |s,d| _d S d S )Nz=_SegmentSynchronizerImpl.playback_finished called after closezQ_SegmentSynchronizerImpl.playback_finished called before text/audio input is done)	text_done
audio_done)extraT)r   r   r   r   rf   rS   rg   r   )r0   r   r   r   r   r    mark_playback_finished  s   

z/_SegmentSynchronizerImpl.mark_playback_finishedc                 C  s   | j r| jjS | jjS r9   )r   rf   rX   r[   rL   r   r   r    synchronized_transcript  s   z0_SegmentSynchronizerImpl.synchronized_transcriptr
   c                   s`   z$| j 2 z3 d H W }| jr| j|I d H  q6 W | jr$| j  d S d S | jr/| j  w w r9   )r`   rh   capture_textflushr0   r4   r   r   r    r|   %  s   
z&_SegmentSynchronizerImpl._capture_taskc                   s4   | j j2 z3 d H W }| j jj|j|jd q6 d S )N)r)   r%   )rg   rP   rT   r3   r)   r%   )r0   evr   r   r    r~   /  s   z,_SegmentSynchronizerImpl._speaking_rate_taskc                   s  | j  I d H  | jr| jsd S | jd usJ | jj2 z3 d H W }|j}| j	 s8| j I d H  | j
r8 d S | jrA| jsA d S | jrK| j| qt| j|}t | j | j }d}| jj }r|j|krt||}t| jj}||kr| jj|| }	t| |	}n)| jj|| }	t| |	 }n| jr| jj|}
|
| j }t|| jj }td|| | j  }| jrd}| !|d I d H  | j| | !|d I d H  | j j|7  _| j j|7  _q6 d S )Nr   rQ   g       @)"rl   waitr   r   ri   rf   rW   tokenro   is_setr   r`   send_nowaitr:   rd   r   r   rn   rg   rU   r.   rY   rK   r[   rX   r   rs   rT   rF   ceilrZ   r   rr   _sleep_if_not_closed)r0   datawordword_hyphenselapsed	d_hyphens	annotated
target_lenforwarded_lend_texttarget_speaking_unitstarget_hyphensdelayr   r   r    ry   6  sR   


z#_SegmentSynchronizerImpl._main_taskr'   c                   s0    j j|}ttj fdd|D }|S )zCalculate hyphens for text.c                 3  s    | ]	} j |V  qd S r9   )rd   r   )r;   r   rL   r   r    r<   v  s    z9_SegmentSynchronizerImpl._calc_hyphens.<locals>.<genexpr>)rd   r   r   rM   	itertoolschainfrom_iterable)r0   r4   wordshyphensr   rL   r    r   r  s
   z&_SegmentSynchronizerImpl._calc_hyphensr   c                   sL   t tj tj| jg|dI d H  W d    d S 1 sw   Y  d S )N)timeout)
contextlibsuppressrj   TimeoutErrorr   rw   )r0   r   r   r   r    r   z  s   "z-_SegmentSynchronizerImpl._sleep_if_not_closedc                   sl   | j rd S | jd  | j  | j  | jj I d H  | j	j
 I d H  | jI d H  | jI d H  d S r9   )r   rw   
set_resultrl   rp   ro   rf   rW   acloserg   rP   r}   r   rL   r   r   r    r   ~  s   

z_SegmentSynchronizerImpl.acloseN)r]   r   r^   r_   r*   r+   r*   rR   r   r   r*   r+   r*   r+   r4   r5   r*   r+   )r   r   r   rR   r*   r+   )r*   r5   )r4   r5   r*   r'   )r   r   r*   r+   )r   r   r   __doc__r   rN   r   r   r   r   r   r   r   r   r   r   r   r   r	   log_exceptionsr   r|   r~   ry   r   r   r   r   r   r   r    r\      s8    



	



	



	

;
r\   c                      s   e Zd ZdZdejjedd. fddZe	d/ddZ
e	d0ddZe	d1ddZd2ddZd3ddZeed d4d$d%Zd5d(d)Zd2d*d+Zd2d,d-Z  ZS )6TranscriptSynchronizerz
    Synchronizes text with audio playback timing.

    This class is responsible for synchronizing text with audio playback timing.
    It currently assumes that the first push_audio is starting the audio playback of a segment.
    g      ?)r   r   r   next_in_chain_audioio.AudioOutputnext_in_chain_textr_   r   r   r   r   r   "NotGivenOr[tokenize.WordTokenizer]r*   r+   c                  s   t    t| |d| _t| |d| _d\| _| _t|||p&t	j
jddddt d| _d| _d| _d| _t| j|d| _d | _d S )N)r^   )TTTF)retain_formatignore_punctuationsplit_character)r   r   r   r   r]   r^   )superr   _SyncedTextOutput_text_output_SyncedAudioOutput_audio_output_text_attached_audio_attachedr   r   basicWordTokenizerr   rd   _enabled_closed_pausedr\   _impl_rotate_segment_atask)r0   r   r   r   r   r   	__class__r   r    r     s$   
	
zTranscriptSynchronizer.__init__r   c                 C     | j S r9   )r   rL   r   r   r    audio_output     z#TranscriptSynchronizer.audio_outputr   c                 C  r   r9   )r   rL   r   r   r    text_output  r   z"TranscriptSynchronizer.text_outputrR   c                 C  r   r9   )r   rL   r   r   r    enabled  r   zTranscriptSynchronizer.enabledc                   s*   d| _ |  I d H  | j I d H  d S NT)r   barrierr   r   rL   r   r   r    r     s   zTranscriptSynchronizer.acloser   c                 C  s4   | j |krd S || _ | jr| j r|   d S d S r9   )r   r   rS   rotate_segment)r0   r   r   r   r    set_enabled  s   
z"TranscriptSynchronizer.set_enabled)audio_attachedtext_attachedr   NotGivenOr[bool]r   c                C  s2   t |r|| _t |r|| _| | jo| j d S r9   )r   r   r   r   )r0   r   r   r   r   r    _on_attachment_changed  s
   z-TranscriptSynchronizer._on_attachment_changedold_taskasyncio.Task[None] | Nonec                   s   |rt t |I d H  W d    n1 sw   Y  z
| j I d H  W n ty5   td Y nw t| j| j	j
d| _| jrJ| j  d S d S )Nz9failed to close segment synchronizer impl during rotationr   )r   r   	Exceptionr   r   r   	exceptionr\   rd   r   rh   r   r   )r0   r   r   r   r    _rotate_segment_task  s    
z+TranscriptSynchronizer._rotate_segment_taskc                 C  s<   | j rd S | jr| j std t| | j| _d S )NzCrotate_segment called while previous segment is still being rotated)r   r   rS   r   r   rj   rx   r   rL   r   r   r    r     s   


z%TranscriptSynchronizer.rotate_segmentc                   s8   | j d u rd S | j  s| j I d H  | j  rd S d S r9   )r   rS   rL   r   r   r    r     s   

zTranscriptSynchronizer.barrier)r   r   r   r_   r   r   r   r   r   r   r*   r+   )r*   r   )r*   r   r   r   )r   rR   r*   r+   )r   r   r   r   r*   r+   )r   r   r*   r+   )r   r   r   r   r   r   r   r   r   rN   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r    r     s(    #



r   c                      s   e Zd Zd# fddZd$ fddZd% fddZd%ddZddd& fddZd% fddZd% fddZ	d% fdd Z
d% fd!d"Z  ZS )'r   synchronizerr   r^   r   r*   r+   c                  s4   t  jd||jtjddd || _|| _d| _d S )Nr   T)r   )labelr^   sample_ratecapabilitiesrQ   )r   r   r   r   AudioOutputCapabilitiesrh   _synchronizer_pushed_durationr0   r   r^   r   r   r    r   	  s   

z_SyncedAudioOutput.__init__r   r   c                   s   | j  I d H  | j|I d H  t |I d H  |  j|j7  _| j js)d S | j jj	r@t
d | j   | j  I d H  | j j| d S )NzQ_SegmentSynchronizerImpl audio marked as ended in capture audio, rotating segment)r   r   rh   capture_framer   r   r   r   r   r   r   r   r   r   r   r   r   r    r     s   

z _SyncedAudioOutput.capture_framec                   sD   t    | j  | jjsd S | js| j  d S | jj  d S r9   )	r   r   rh   r   r   r   r   r   r   rL   r   r   r    r   ,  s   


z_SyncedAudioOutput.flushc                 C  s   | j   d S r9   )rh   clear_bufferrL   r   r   r    r  :  s   z_SyncedAudioOutput.clear_bufferN)r   r   r   r   rR   r   
str | Nonec                  s\   | j jst j|||d d S | j jj||d t j||| j jjd | j   d| _d S )N)r   r   r   )r   r   rQ   )	r   r   r   on_playback_finishedr   r   r   r   r   )r0   r   r   r   r   r   r    r  >  s"   

z'_SyncedAudioOutput.on_playback_finishedc                      t    | jjdd d S )NTr   r   on_attachedr   r   rL   r   r   r    r  Y     
z_SyncedAudioOutput.on_attachedc                   r  )NFr  r   on_detachedr   r   rL   r   r   r    r
  ]  r  z_SyncedAudioOutput.on_detachedc                   0   t    d| j_| jjjs| jj  d S d S r   )r   r   r   r   r   r   rL   r   r   r    r   a  
   

z_SyncedAudioOutput.pausec                   r  NF)r   r   r   r   r   r   rL   r   r   r    r   h  r  z_SyncedAudioOutput.resume)r   r   r^   r   r*   r+   r   r   )r   r   r   rR   r   r  r*   r+   )r   r   r   r   r   r   r  r  r  r
  r   r   r   r   r   r   r    r     s    
	r   c                      sN   e Zd Zd fddZdddZdddZd fddZd fddZ  ZS )r   r   r   r^   r_   r*   r+   c                  s&   t  jd|d || _|| _d| _d S )Nr   )r   r^   F)r   r   rh   r   
_capturingr   r   r   r    r   q  s   
z_SyncedTextOutput.__init__r4   r5   c                   s|   | j  I d H  | j js| jr| j|I d H  d S d| _| j jjr5t	d | j 
  | j  I d H  | j j| d S )NTzO_SegmentSynchronizerImpl text marked as ended in capture text, rotating segment)r   r   r   rh   r   r  r   r   r   r   r   r   r   r   r   r    r   y  s   

z_SyncedTextOutput.capture_textc                 C  s<   | j js| jr| j  d S | jsd S d| _| j j  d S r  )r   r   rh   r   r  r   r   rL   r   r   r    r     s   
z_SyncedTextOutput.flushc                   r  )NTr   r  rL   r   r   r    r    r  z_SyncedTextOutput.on_attachedc                   r  )NFr  r	  rL   r   r   r    r
    r  z_SyncedTextOutput.on_detached)r   r   r^   r_   r*   r+   r   r   )	r   r   r   r   r   r   r  r
  r   r   r   r   r    r   p  s    

r   )'
__future__r   rj   r   r   r   collections.abcr   dataclassesr   r   numpyrF   livekitr   r=   r   r	   logr   typesr   r   r   r   _speaking_rater   r   rq   r   r!   rO   rV   r\   r   AudioOutputr   
TextOutputr   r   r   r   r    <module>   s<    O  }h