+
    ~j-                    *   ^ RI Ht ^ RIt^ RIt^ RIHt ^ RIt^ RIt^ RI	H
t
 ^ RIHt ^RIHt ^RIHt ]]P$                  ,          ]P$                  ,          t]P(                  t]P(                  tR R	 lt ! R
 R4      tRR R llt ! R R4      tR# )    )annotationsN)AsyncGenerator)	DTypeLike)rtc)logger)cancel_and_waitc                    V ^8  d   QhRRRR/# )   framesAudioBufferreturnfloat )formats   "o/Users/mitch_tango/dev/rabbit-r1-livekit/agent/.venv/lib/python3.14/site-packages/livekit/agents/utils/audio.py__annotate__r      s      [ U     c                j    \        V \        4      '       d   \        R V  4       4      # V P                  # )a  
Calculate the total duration of audio frames.

This function computes the total duration of audio frames in seconds.
It accepts either a list of `rtc.AudioFrame` objects or a single `rtc.AudioFrame` object.

Parameters:
- frames (AudioBuffer): A list of `rtc.AudioFrame` instances or a single `rtc.AudioFrame` instance.

Returns:
- float: The total duration in seconds of all frames provided.
c              3  8   "   T F  qP                   x  K  	  R # 5iN)duration).0frames   & r   	<genexpr>+calculate_audio_duration.<locals>.<genexpr>%   s     6ve>>vs   )
isinstancelistsumr   )r   s   &r   calculate_audio_durationr      s,     &$6v666r   c                  V    ] tR t^*tRt^tRR R lltR R lt]tR R lt	R	 R
 lt
RtR# )AudioByteStreamu  Buffer and chunk audio byte data into fixed-size frames.

Accepts variable-sized byte chunks (e.g. from a network stream or file) and
emits consistently-sized ``rtc.AudioFrame`` objects.

Two modes of operation:

* **Fixed** (``progressive=False``, the default): every emitted frame is
  exactly ``samples_per_channel`` samples long.
* **Progressive** (``progressive=True``): the *first* emitted frame is only
  20 ms of audio.  Each subsequent frame doubles in size until
  ``samples_per_channel`` is reached.  This minimises time-to-first-audio
  while giving the pipeline a brief warm-up before reaching full frame
  sizes.

Example with ``sample_rate=16000, samples_per_channel=3200`` (200 ms) and
``progressive=True``::

    Frame 1:  320 samples  ( 20 ms)
    Frame 2:  640 samples  ( 40 ms)
    Frame 3: 1280 samples  ( 80 ms)
    Frame 4: 2560 samples  (160 ms)
    Frame 5: 3200 samples  (200 ms)   ← target reached
    Frame 6: 3200 samples  (200 ms)
    ...
Nc          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r
   sample_rateintnum_channelssamples_per_channelz
int | Noneprogressiveboolr   Noner   )r   s   "r   r   AudioByteStream.__annotate__H   sC     "F "F"F "F (	"F
 "F 
"Fr   c                   Wn         W n        Vf
   V^
,          pV\        P                  ! \        P                  4      ,          V n        W0P
                  ,          V n        \        4       V n        V'       dF   WP                  ,          R,          p\        WPP
                  ,          V P                  4      V n        MV P                  V n        V P                  V n        R# )a  
Args:
    sample_rate: Audio sample rate in Hz.
    num_channels: Number of audio channels.
    samples_per_channel: Target samples per channel in each emitted frame.
        Defaults to ``sample_rate // 10`` (100 ms).
    progressive: When *True*, start with a small 20 ms frame and double
        the frame size on each subsequent emission until
        ``samples_per_channel`` is reached.
Ni  )_sample_rate_num_channelsctypessizeofc_int16_bytes_per_sample_target_bytes_per_frame	bytearray_buf_MIN_PROGRESSIVE_MSmin_initial_bytes_per_frame_current_bytes_per_frame)selfr#   r%   r&   r'   min_sampless   &&&&& r   __init__AudioByteStream.__init__H   s    " ()&"-"3!-fnn0M!M':=S=S'S$K	%(@(@@DHK,/444d6R6R-D) -1,H,HD)(,(E(E%r   c                    V ^8  d   QhRRRR/# )r
   datazbytes | memoryviewr   list[rtc.AudioFrame]r   )r   s   "r   r   r*   l   s     ) )+ )0D )r   c           
     0   V P                   P                  V4       . p\        V P                   4      V P                  8  d   V P                   RV P                   pV P                   RV P                  1 VP	                  \
        P                  ! VV P                  V P                  \        V4      V P                  ,          R7      4       V P                  V P                  8  g   K  \        V P                  ^,          V P                  4      V n        K  V# )a{  
Add audio data to the buffer and retrieve fixed-size frames.

Parameters:
    data (bytes): The incoming audio data to buffer.

Returns:
    list[rtc.AudioFrame]: A list of `AudioFrame` objects of fixed size.

The method appends the incoming data to the internal buffer.
While the buffer contains enough data to form complete frames,
it extracts the data for each frame, creates an `AudioFrame` object,
and appends it to the list of frames to return.

This allows you to feed in variable-sized chunks of audio data
(e.g., from a stream or file) and receive back a list of
fixed-size audio frames ready for processing or transmission.
Nr>   r#   r%   r&   )r4   extendlenr8   appendr   
AudioFramer,   r-   r1   r2   r6   )r9   r>   r   
frame_datas   &&  r   pushAudioByteStream.pushl   s    & 			$))n = ==#BT%B%BCJ		9D999:MM# $ 1 1!%!3!3(+J4;Q;Q(Q	 ,,t/K/KK0311A5t7S7S1- r   c                   V ^8  d   QhRR/# )r
   r   r?   r   )r   s   "r   r   r*      s        +  r   c                   \        V P                  4      ^ 8X  d   . # \        V P                  4      V P                  ,          ^ 8w  d   \        P                  ! R4       . # \
        P                  ! V P                  P                  4       V P                  V P                  \        V P                  4      V P                  ,          R7      .pV P                  P                  4        V# )a^  
Flush the buffer and retrieve any remaining audio data as a frame.

Returns:
    list[rtc.AudioFrame]: A list containing any remaining `AudioFrame` objects.

This method processes any remaining data in the buffer that does not
fill a complete frame. If the remaining data forms a partial frame
(i.e., its size is not a multiple of the expected sample size), a warning is
logged and an empty list is returned. Otherwise, it returns the final
`AudioFrame` containing the remaining data.

Use this method when you have no more data to push and want to ensure
that all buffered audio data has been processed.
z8AudioByteStream: incomplete frame during flush, droppingrA   )rC   r4   r1   r   warningr   rE   copyr,   r-   clear)r9   r   s   & r   flushAudioByteStream.flush   s      tyy>QItyy>D222a7NNUVI NNYY^^% --!//$'		Nd6L6L$L	
 			r   c                   V ^8  d   QhRR/# r
   r   r)   r   )r   s   "r   r   r*      s     F Ft Fr   c                \    V P                   P                  4        V P                  V n        R# )zDiscard all buffered data and reset progressive frame sizing.

After clearing, the next :meth:`push` will start from the initial
(small) frame size again, ensuring low latency on the first frame
after an interruption.
N)r4   rM   r7   r8   r9   s   &r   rM   AudioByteStream.clear   s      			(,(E(E%r   )r4   r1   r8   r7   r-   r,   r2   )NF)__name__
__module____qualname____firstlineno____doc__r5   r;   rG   writerN   rM   __static_attributes__r   r   r   r!   r!   *   s5    6 "FH)V E DF Fr   r!   c               (    V ^8  d   QhRRRRRRRR/# )r
   	file_pathstrr#   r$   r%   r   z$AsyncGenerator[rtc.AudioFrame, None]r   )r   s   "r   r   r      s,     ( ((!$(<?()(r   c                 a a"   ^RI Hp V! WR7      oR VV 3R llp\        P                  ! V! 4       4      p S  Rj  xL
  pV5x  K   LD \	        T4      G Rj  xL 
  SP                  4       G Rj  xL 
  M2  \	        T4      G Rj  xL 
  SP                  4       G Rj  xL 
  i ; iTP                  4       '       d5   TP                  4       '       g   TP                  4       ;p'       d   ThR# R# R# 5i)a  
Decode the audio file into rtc.AudioFrame instances and yield them as an async iterable.
Args:
    file_path (str): The path to the audio file.
    sample_rate (int, optional): Desired sample rate. Defaults to 48000.
    num_channels (int, optional): Number of channels (1 for mono, 2 for stereo). Defaults to 1.
Returns:
    AsyncIterable[rtc.AudioFrame]: An async iterable that yields decoded AudioFrame
)AudioStreamDecoder)r#   r%   c                   V ^8  d   QhRR/# rQ   r   )r   s   "r   r   ,audio_frames_from_file.<locals>.__annotate__   s     
  
 t 
 r   c                 ~  <"    \         P                  ! SR R7      ;_uu_4       GRj  xL
 p  V P                  R4      G Rj  xL
 pV'       g   MSP                  V4       K6  RRR4      GRj  xL
  SP	                  4        R#  L\ LD L  + GRj  xL 
 '       g   i     L1; i  SP	                  4        i ; i5i)rb)modeNi   )aiofilesopenreadrG   	end_input)fchunkdecoderr]   s     r   file_reader+audio_frames_from_file.<locals>.file_reader   s     		 }}YT:::a"#&&,.E LL' ;:  ;. ;::: s   B=$B( BB( BBBB$B( /B
0B( 4B=B( B
B( B%	B
B%	B%	 B( (B::B=N)	codecsr`   asynciocreate_taskr   aclosedone	cancelled	exception)	r]   r#   r%   r`   rm   reader_taskr   excrl   s	   f&&     @r   audio_frames_from_filerx      s      + [TG
  
  %%km4K" 	 	%K	7 k***nn k***nn +"7"7"9"9''))3)I * #:s   5C=A? A AA	A? AA? C=A" C=8A;9C=?B.BB.'B*(B..C=C=C=5C=c                  ~    ] tR t^tR]P
                  RR/R R lltR R ltR R	 ltR
 R lt	R R lt
R R ltRtR# )AudioArrayBufferdtyper#   i>  c               $    V ^8  d   QhRRRRRR/# )r
   buffer_sizer$   r{   r   r#   r   )r   s   "r   r   AudioArrayBuffer.__annotate__   s"     ( (s (9 (VY (r   c               ~    Wn         W n        \        P                  ! WR7      V n        ^ V n        RV n        W0n        R# )zCreate a fixed-size buffer for audio array data.

Args:
    buffer_size: The size of the buffer in samples.
    dtype: The dtype of the buffer.
    sample_rate: The sample rate of the buffer.
)r{   N)_buffer_size_dtypenpzeros_buffer
_start_idx
_resamplerr,   )r9   r}   r{   r#   s   &$$$r   r;   AudioArrayBuffer.__init__   s3     (xx959'r   c                    V ^8  d   QhRRRR/# )r
   r   zrtc.AudioFramer   r$   r   )r   s   "r   r   r~     s     .) .) .)3 .)r   c                   VP                   V P                  8  d   \        R4      h. pV P                  fq   VP                  V P
                  8w  dV   \        P                  ! VP                  V P
                  VP                  \        P                  P                  R7      V n        V P                  '       d\   VP                  V P                  P                  8w  d   \        R4      hVP                  V P                  P                  V4      4       MVP                  V4       \        V4      pV P                   VP                   ,           V P                  ,
          ;p^ 8  d   V P#                  V4       V P$                  V P                   V P                   VP                   ,            pVP                  ^8  d   \&        P(                  ! VP*                  \&        P,                  VP                   VP                  ,          R7      P/                  RVP                  4      p\&        P0                  ! V^\&        P2                  R7      VP                  ,          P5                  \&        P,                  4      VR&   M>\&        P(                  ! VP*                  \&        P,                  VP                   R7      VR&   V ;P                   VP                   ,          un        VP                   # )zPush an audio frame to the buffer.

Args:
    frame: The audio frame to push.

Returns:
    The number of samples written to the buffer.

Raises:
    ValueError: If the frame samples are greater than the buffer size.
z.frame samples are greater than the buffer size)
input_rateoutput_rater%   qualityz#frame sample rates are inconsistent)r{   count)axisr{   :NNN)r&   r   
ValueErrorr   r#   r,   r   AudioResamplerr%   AudioResamplerQualityQUICK_input_raterB   rG   rD   merge_framesr   shiftr   r   
frombufferr>   int16reshaper   int32astype)r9   r   r   
shift_sizeptrarr_i16s   &&    r   
push_frameAudioArrayBuffer.push_frame  s	    $$t'8'88MNN')??"u'8'8D<M<M'M!00 ,, --"//1177	DO ???  DOO$?$?? !FGGMM$//..u56MM% V$//E,E,EEHYHYYYJ]^^JJz"ll4??T__u?X?X-XY!mm

"((%2K2KeN`N`2`gb%,,-  ffW1BHH=ASASS[[CF ]]5::RXXUE^E^_CF5444(((r   c                    V ^8  d   QhRRRR/# )r
   sizer$   r   r)   r   )r   s   "r   r   r~   1  s        #  $  r   c                    \        WP                  4      pV P                  WP                   P                  4       V P                  RV P                  V,
          % V ;P                  V,          un        R# )zbShift the buffer to the left by the given size.

Args:
    size: The size to shift the buffer by.
N)r6   r   r   rL   )r9   r   s   &&r   r   AudioArrayBuffer.shift1  sP     4)15d__1U1Z1Z1\-t-.4r   c                   V ^8  d   QhRR/# )r
   r   z
np.ndarrayr   )r   s   "r   r   r~   ;  s     6 6j 6r   c                	P    V P                   R V P                   P                  4       # r   )r   r   rL   rS   s   &r   rh   AudioArrayBuffer.read;  s!    ||-doo.3355r   c                   V ^8  d   QhRR/# rQ   r   )r   s   "r   r   r~   >  s      t r   c                	J    ^ V n         V P                  P                  ^ 4       R# )r   N)r   r   fillrS   s   &r   resetAudioArrayBuffer.reset>  s    !r   c                   V ^8  d   QhRR/# )r
   r   r$   r   )r   s   "r   r   r~   B  s       r   c                	    V P                   # r   )r   rS   s   &r   __len__AudioArrayBuffer.__len__B  s    r   )r   r   r   r   r,   r   N)rU   rV   rW   rX   r   r   r;   r   r   rh   r   r   r[   r   r   r   rz   rz      s9    (rxx (\a (.)` 6 r   rz   )i     )
__future__r   rp   r.   collections.abcr   rf   numpyr   numpy.typingr   livekitr   logr   	aio.utilsr   r   rE   r   combine_audio_framescombine_framesr   r   r!   rx   rz   r   r   r   <module>r      sx    "   *   "   & 3>>"S^^3))''&YF YFx(VR Rr   