+
    ~jA                       ^ RI Ht ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	H
t
 ^ RIHtHt ^ RIHtHt ^ RIt^ RIHt ^RIHt ^RIHt ^R	IHtHt ^R
IHtHt ^RIH t  ^RI!H"t" ^RI#H$t$ ^RI%H&t& ]PN                  ! 4       t(]PR                  ! ](PT                  4        ! R R]PV                  4      t,]	]PZ                  ,          ].,          ],,          t/ ! R R]4      t0Rt1Rt2 ! R R4      t3 ! R R4      t4R R lt5R# )    )annotationsN)AsyncGeneratorAsyncIterator	Generator)as_filefiles)Any
NamedTuple)rtc)get_job_contextlogger)	NOT_GIVEN
NotGivenOr)is_givenlog_exceptions)cancel_and_waitaudio_frames_from_file)AgentSession)AgentStateChangedEventc                  >    ] tR t^tRtRtRtRtRtRt	Rt
R R	 ltR
tR# )BuiltinAudioClipzcity-ambience.oggzforest-ambience.oggzoffice-ambience.oggzcrowded-room.oggzkeyboard-typing.oggzkeyboard-typing2.oggzhold_music.oggc                   V ^8  d   QhRR/# )   returnstr )formats   "z/Users/mitch_tango/dev/rabbit-r1-livekit/agent/.venv/lib/python3.14/site-packages/livekit/agents/voice/background_audio.py__annotate__BuiltinAudioClip.__annotate__&   s     F Fc F    c                	    \        R 4      V P                  ,          p\        \        P	                  \        V4      4      4      # )zlivekit.agents.resources)r   valuer   _resource_stackenter_contextr   )self	file_paths   & r    pathBuiltinAudioClip.path&   s1    45

B	?001CDEEr#   r   N)__name__
__module____qualname____firstlineno__CITY_AMBIENCEFOREST_AMBIENCEOFFICE_AMBIENCECROWDED_ROOMKEYBOARD_TYPINGKEYBOARD_TYPING2
HOLD_MUSICr*   __static_attributes__r   r#   r    r   r      s2    'M+O+O%L+O-!JF Fr#   r   c                  B    ] tR t^.t$ RtR]R&   RtR]R&   RtR]R&   RtR	# )
AudioConfigz
Definition for the audio to be played in the background

Args:
    volume: The volume of the audio (0.0-1.0)
    probability: The probability of the audio being played, when multiple
        AudioConfigs are provided (0.0-1.0)
AudioSourcesource      ?floatvolumeprobabilityr   N)	r,   r-   r.   r/   __doc____annotations__r>   r?   r7   r   r#   r    r9   r9   .   s#     FEKr#   r9   i  background_audioc                      ] tR t^EtR]R]R^/R R lltR R ltR R	 ltR
 R ltRR/R R llt	R]R]/R R llt
R R ltR R ltR R lt]! ]R7      R R l4       t]! ]R7      R R l4       tR R  ltR!tR"# )#BackgroundAudioPlayerambient_soundthinking_soundstream_timeout_msc               (    V ^8  d   QhRRRRRRRR/# )r   rE   z@NotGivenOr[AudioSource | AudioConfig | list[AudioConfig] | None]rF   rG   intr   Noner   )r   s   "r    r!   "BackgroundAudioPlayer.__annotate__F   s5     08 08 X08
	08 08 
08r#   c               l   \        V4      '       d   TMRV n        \        V4      '       d   TMRV n        \        P                  ! R^\
        R7      V n        \        P                  ! R^R^VR7      V n        RV n	        \        P                  ! 4       V n        RV n        . V n        RV n        RV n        R# )uk  
Initializes the BackgroundAudio component with optional ambient and thinking sounds.

This component creates and publishes a continuous audio track to a LiveKit room while managing
the playback of ambient and agent “thinking” sounds. It supports three types of audio sources:
- A BuiltinAudioClip enum value, which will use a pre-defined sound from the package resources
- A file path (string) pointing to an audio file, which can be looped.
- An AsyncIterator that yields rtc.AudioFrame

When a list (or AudioConfig) is supplied, the component considers each sound’s volume and probability:
- The probability value determines the chance that a particular sound is selected for playback.
- A total probability below 1.0 means there is a chance no sound will be selected (resulting in silence).

Args:
    ambient_sound (NotGivenOr[Union[AudioSource, AudioConfig, List[AudioConfig], None]], optional):
        The ambient sound to be played continuously. For file paths, the sound will be looped.
        For AsyncIterator sources, ensure the iterator is infinite or looped.

    thinking_sound (NotGivenOr[Union[AudioSource, AudioConfig, List[AudioConfig], None]], optional):
        The sound to be played when the associated agent enters a “thinking” state. This can be a single
        sound source or a list of AudioConfig objects (with volume and probability settings).

Ni  )queue_size_msi  )	blocksizecapacityrG   )r   _ambient_sound_thinking_soundr   r:   _AUDIO_SOURCE_BUFFER_MS_audio_source
AudioMixer_audio_mixerpublicationasyncioLock_lock_mixer_atask_play_tasks_ambient_handle_thinking_handle)r(   rE   rF   rG   s   &$$$r    __init__BackgroundAudioPlayer.__init__F   s    B 08/F/FmD19.1I1I~t __UAE\]NN1qDU
 >B\\^
7;572637r#   c                    V ^8  d   QhRRRR/# )r   soundszlist[AudioConfig]r   zAudioConfig | Noner   )r   s   "r    r!   rK   x   s      .? DV r#   c                x   \        R V 4       4      pV^ 8:  d   R# VR8  d   \        P                  ! 4       V8  d   R# VR8:  d   RMTp\        P                  ! 4       \        VR4      ,          pRpV F;  pVP                  ^ 8:  d   K  VP                  V,          pWW,          pWE8:  g   K9  Vu # 	  VR,          # )z
Selects a sound from a list of BackgroundSound based on their probabilities.
Returns None if no sound is selected (when sum of probabilities < 1.0).
c              3  8   "   T F  qP                   x  K  	  R # 5iN)r?   ).0sounds   & r    	<genexpr>@BackgroundAudioPlayer._select_sound_from_list.<locals>.<genexpr>}   s     Fve 1 1vs   Nr<   g        )sumrandomminr?   )r(   ra   total_probabilitynormalize_factorr
cumulativerf   	norm_probs   &&      r    _select_sound_from_list-BackgroundAudioPlayer._select_sound_from_listx   s    
  FvFF!s"v}}9J'J"3s":3@QMMOc"3S99
E  A%)),<<I#J  bzr#   c                    V ^8  d   QhRRRR/# )r   r;   z4AudioSource | AudioConfig | list[AudioConfig] | Noner   z tuple[AudioSource, float] | Noner   )r   s   "r    r!   rK      s      J	)r#   c                	l   Vf   R # \        V\        4      '       d   V P                  V4      R3# \        V\        4      '       d0   V P	                  V4      pVf   R # VP
                  VP                  3# \        V\        4      '       d(   V P                  VP
                  4      VP                  3# VR3# )Nr<   )
isinstancer   _normalize_builtin_audiolistrr   r;   r>   r9   )r(   r;   selecteds   && r    _normalize_sound_source-BackgroundAudioPlayer._normalize_sound_source   s     >f.//008#==%%33F;H??HOO33,,00?NNs{r#   c                    V ^8  d   QhRRRR/# )r   r;   r:   r   z#AsyncIterator[rtc.AudioFrame] | strr   )r   s   "r    r!   rK      s      { ?b r#   c                	R    \        V\        4      '       d   VP                  4       # V# rd   )rv   r   r*   )r(   r;   s   &&r    rw   .BackgroundAudioPlayer._normalize_builtin_audio   s!    f.//;;= Mr#   loopFc               $    V ^8  d   QhRRRRRR/# )r   audioz-AudioSource | AudioConfig | list[AudioConfig]r   boolr   
PlayHandler   )r   s   "r    r!   rK      s(     1 1<1 	1
 
1r#   c                 a aa S P                   '       g   \        R4      hS P                  V4      pVf   \        4       oSP	                  4        S# Vw  rEV'       d"   \        V\        4      '       d   \        R4      h\        4       o\        P                  ! S P                  SWEV4      4      oSP                  V V3R l4       SP                  V3R l4       S P                  P                  S4       S# )aQ  
Plays an audio once or in a loop.

Args:
    audio (Union[AudioSource, AudioConfig, List[AudioConfig]]):
        The audio to play. Can be:
        - A string pointing to a file path
        - An AsyncIterator that yields `rtc.AudioFrame`
        - An AudioConfig object with volume and probability
        - A list of AudioConfig objects, where one will be selected based on probability

        If a string is provided and `loop` is True, the sound will be looped.
        If an AsyncIterator is provided, it is played until exhaustion (and cannot be looped
        automatically).
    loop (bool, optional):
        Whether to loop the audio. Only applicable if `audio` is a string or contains strings.
        Defaults to False.

Returns:
    PlayHandle: An object representing the playback handle. This can be
    awaited or stopped manually.
zBackgroundAudio is not startedz}Looping sound via AsyncIterator is not supported. Use a string file path or your own 'infinite' AsyncIterator with loop=Falsec                :   < SP                   P                  S4      # rd   )r[   remove)_r(   tasks   &r    <lambda>,BackgroundAudioPlayer.play.<locals>.<lambda>   s    )9)9)@)@)Fr#   c                $   < SP                  4       # rd   )_mark_playout_done)r   play_handles   &r    r   r      s    )G)G)Ir#   )rZ   RuntimeErrorrz   r   r   rv   r   
ValueErrorrW   create_task
_play_taskadd_done_callbackr[   append)r(   r   r   
normalizedsound_sourcer>   r   r   s   f&$   @@r    playBackgroundAudioPlayer.play   s    8    ?@@11%8
$,K**,)J|];; P  !l""4??;VZ#[\FGIJ%r#   agent_sessiontrack_publish_optionsc               (    V ^8  d   QhRRRRRRRR/# )	r   roomzrtc.Roomr   zNotGivenOr[AgentSession]r   z#NotGivenOr[rtc.TrackPublishOptions]r   rJ   r   )r   s   "r    r!   rK      s;     6I 6I 6I 0	6I
  C6I 
6Ir#   c                 "   V P                   ;_uu_4       GRj  xL
  Wn        T;'       g    RV n        T;'       g    RV n         \	        4       pVP                  4       '       d   \        P                  ! R4       T P                  4       G Rj  xL
  \        P                  ! T P                  4       4      T n        T P                  '       d'   T P                  P                  RT P                  4       T P                   '       dx   T P#                  T P                   4      pT'       dU   Tw  rg\%        Yg4      p\'        T\(        4      '       d   T P+                  TRR7      T n        MT P+                  T4      T n        RRR4      GRj  xL
  R#  ELx  \         d     EL%i ; i EL L  + GRj  xL 
 '       g   i     R# ; i5i)a  
Starts the background audio system, publishing the audio track
and beginning playback of any configured ambient sound.

If `ambient_sound` is provided (and contains file paths), they will loop
automatically. If `ambient_sound` contains AsyncIterators, they are assumed
to be already infinite or looped.

Args:
    room (rtc.Room):
        The LiveKit Room object where the audio track will be published.
    agent_session (NotGivenOr[AgentSession], optional):
        The session object used to track the agent's state (e.g., "thinking").
        Required if `thinking_sound` is provided.
    track_publish_options (NotGivenOr[rtc.TrackPublishOptions], optional):
        Options used when publishing the audio track. If not given, defaults will
        be used.
NzLBackground audio is not supported in console mode. Audio will not be played.agent_state_changedT)r   )rY   _room_agent_session_track_publish_optionsr   is_fake_jobr   warningr   _publish_trackrW   r   _run_mixer_taskrZ   on_agent_state_changedrP   rz   r9   rv   r   r   r\   )	r(   r   r   r   job_ctxr   r   r>   selected_sounds	   &$$$     r    startBackgroundAudioPlayer.start   sR    2 ::::J"/"7"74D*?*G*G4D')+&&((NNf %%''' ' 3 3D4H4H4J KD"""##&&'<d>W>WX"""!99$:M:MN
+5(L%0%FN!,44/3yydy/S,/3yy/H,; ::    ( :::s   G
FG
 F- F-	6F?F-F(>F-7F-
"F--AF-G
F+G
F%!F-$F%%F-+G
-G	3F64
G	?G		G
c                   V ^8  d   QhRR/# r   r   rJ   r   )r   s   "r    r!   rK     s     T Td Tr#   c           	       "   V P                   ;_uu_4       GRj  xL
  V P                  '       g    RRR4      GRj  xL
  R# \        V P                  !  G Rj  xL
  \        V P                  4      G Rj  xL
  RV n        V P                  P                  4       G Rj  xL
  V P                  P                  4       G Rj  xL
  V P                  '       d'   V P                  P                  RV P                  4       \        P                  ! \        4      ;_uu_ 4        V P                  \        4      pVe8   V P                  P                   P#                  VP$                  4      G Rj  xL
  RRR4       RRR4      GRj  xL
  R#  ELr ELR EL8 EL L L L.  + '       g   i     L4; i L+  + GRj  xL 
 '       g   i     R# ; i5i)zw
Gracefully closes the background audio system, canceling all ongoing
playback tasks and unpublishing the audio track.
Nr   )rY   rZ   r   r[   rU   acloserS   r   offr   
contextlibsuppress	Exception_find_publication_by_name_TRACK_NAMEr   local_participantunpublish_tracksid)r(   currents   & r    r   BackgroundAudioPlayer.aclose  s8    
 ::::$$$ :: "4#3#3444!$"3"3444 $D##**,,,$$++---"""##''(=t?X?XY$$Y// 88E&**66FFw{{SSS 0 :: 54 -- T 0/ :::s   GFGF4GFGF4FF48F9(F4!F"!F4FF4AF4"AF	.F/F	3F4;GF2GGF4F4F4F4F	F/*F42G4G	:F=;
G	G		Gc                    V ^8  d   QhRRRR/# )r   namer   r   z rtc.LocalTrackPublication | Noner   )r   s   "r    r!   rK   3  s      c 6V r#   c                	    V P                   P                  P                  P                  4        F  pVP                  V8X  g   K  Vu # 	  R # rd   )r   r   track_publicationsvaluesr   )r(   r   pubs   && r    r   /BackgroundAudioPlayer._find_publication_by_name3  s<    :://BBIIKCxx4
 L r#   c                    V ^8  d   QhRRRR/# )r   evr   r   rJ   r   )r   s   "r    r!   rK   9  s     ) )'= )$ )r#   c                	x   V P                   '       g   R # VP                  R8X  dg   V P                  '       d#   V P                  P                  4       '       g   R # V P                   f   Q hV P	                  V P                   4      V n        R # V P                  '       d   V P                  P                  4        R # R # )Nthinking)rQ   	new_stater]   doner   stop)r(   r   s   &&r    r   *BackgroundAudioPlayer._agent_state_changed9  s    ###<<:%$$$T-B-B-G-G-I-I''333$(IId.B.B$CD!"""!!&&( #r#   r   c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r   r   r   rf   r:   r>   r=   r   r   r   rJ   r   )r   s   "r    r!   rK   H  s4     3' 3'%3'.93'CH3'PT3'	3'r#   c           	     	  aaaa"   \        S\        4      '       d   SP                  4       o\        S\        4      '       d    V'       d   \	        S4      oM\        S4      oR oR VVVV3R llpV! 4       p V P                  P                  V4       SP                  4       G Rj  xL
  V P                  P                  V4       SP                  4        \        P                  ! ^ 4      G Rj  xL
  SP                  P                  4       '       dH   Ro\        P                   ! \"        4      ;_uu_ 4        VP%                  4       G Rj  xL
  RRR4       R# R#  L Lo L  + '       g   i     R# ; i  T P                  P                  T4       SP                  4        \        P                  ! ^ 4      G Rj  xL 
  SP                  P                  4       '       d[   Ro\        P                   ! \"        4      ;_uu_ 4        TP%                  4       G Rj  xL 
  RRR4       i   + '       g   i     i ; ii ; i5i)Fc                   V ^8  d   QhRR/# )r   r   $AsyncGenerator[rtc.AudioFrame, None]r   )r   s   "r    r!   6BackgroundAudioPlayer._play_task.<locals>.__annotate__V  s     	1 	1$H 	1r#   c                  <"    S  R j  xL
  p S'       d    EMSR8w  d   \         P                  ! V P                  \         P                  R7      P	                  \         P
                  4      pV^
\         P                  ! S4      ,          ,          p\         P                  ! VRRVR7       \        P                  ! VP	                  \         P                  4      P                  4       V P                  V P                  V P                  R7      5x  EK  V 5x  EK  SP                  4        R #  EL&ED(L  SP                  4        i ; i5i)Nr<   )dtypei  )out)datasample_ratenum_channelssamples_per_channeli )np
frombufferr   int16astypefloat32log10clipr   
AudioFrametobytesr   r   r   r   )framer   r   rf   stoppedr>   s     r    _gen_wrapper6BackgroundAudioPlayer._play_task.<locals>._gen_wrapperV  s     1#( $ $%}!}}UZZrxxHOOPRPZPZ[rxx'7 88fe>!nn!%RXX!6!>!>!@(-(9(9).););050I0I	  $
 ..0)$5( ..0s=   ED7 D4D1D4DD7 E1D44D7 7E		ENT)rv   r   r*   r   _loop_audio_framesr   rU   
add_streamwait_for_playoutremove_streamr   rW   sleep	_stop_futr   r   r   r   r   )r(   r   rf   r>   r   r   genr   s   &fff&  @r    r    BackgroundAudioPlayer._play_taskG  s     e-..JJLEeS!!*51.u5	1 	10 n	'((-..000++C0**,--"""$$))++((66**,&& 76 , 1
 #
 ' 766 ++C0**,--"""$$))++((66**,&& 7666 ,s   AI ,I 8.E7 &E'E7 +AI /E0#I $I 8E#E!E#I E7 I !E##E4	.	I 7AH=<F?=$H="$H=H)	HH)	 	H=)H94	H==I c                   V ^8  d   QhRR/# r   r   )r   s   "r    r!   rK   ~  s     : :t :r#   c                	   "   V P                     R j  xL
  pV P                  P                  V4      G R j  xL
  K/   L* LD-R # 5ird   )rU   rS   capture_frame)r(   r   s   & r    r   %BackgroundAudioPlayer._run_mixer_task}  sA     ,, 	: 	:%$$225999	:9 -s3   AA>A AA AA AAc                   V ^8  d   QhRR/# r   r   )r   s   "r    r!   rK     s     
 
d 
r#   c                	@  "   V P                   e   R # \        P                  P                  \        V P
                  4      pV P                  P                  P                  YP                  ;'       g    \        P                  ! 4       4      G R j  xL
 V n         R #  L5ird   )rV   r   LocalAudioTrackcreate_audio_trackr   rS   r   r   publish_trackr   TrackPublishOptions)r(   tracks   & r    r   $BackgroundAudioPlayer._publish_track  ss     '##66{DDVDVW!%!=!=!K!K..KK#2I2I2K"
 
 
s   A0B3BBB)r   r\   rP   rU   rS   rY   rZ   r[   r   r]   rQ   r   rV   N)r,   r-   r.   r/   r   r^   rr   rz   rw   r   r   r   r   r   r   r   r   r   r   r7   r   r#   r    rD   rD   E   s    08 [d08 08 "%08d8$1 	1f6I 3<	6I
 FO6IpT8) 6"3' #3'j 6": #:
 
r#   rD   c                  ^    ] tR tRtR R 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# )r   i  c                   V ^8  d   QhRR/# r   r   )r   s   "r    r!   PlayHandle.__annotate__  s     0 0$ 0r#   c                	    \         P                  R ,          ! 4       V n        \         P                  R ,          ! 4       V n        R # rd   )rW   Future	_done_futr   r(   s   &r    r^   PlayHandle.__init__  s(     -/ -/r#   c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r    r!   r     s     % %d %r#   c                6    V P                   P                  4       # )z1
Returns True if the sound has finished playing.
)r   r   r   s   &r    r   PlayHandle.done  s     ~~""$$r#   c                   V ^8  d   QhRR/# r   r   )r   s   "r    r!   r     s     	& 	&d 	&r#   c                   V P                  4       '       d   R# \        P                  ! \        P                  4      ;_uu_ 4        V P
                  P                  R4       V P                  4        RRR4       R#   + '       g   i     R# ; i)z
Stops the sound from playing.
N)r   r   r   rW   InvalidStateErrorr   
set_resultr   r   s   &r    r   PlayHandle.stop  sV     99;;  !:!:;;NN%%d+##% <;;;s   ,A;;B	c                   V ^8  d   QhRR/# r   r   )r   s   "r    r!   r     s     - - -r#   c                b   "   \         P                  ! V P                  4      G Rj  xL
  R#  L5i)z(
Waits for the sound to finish playing.
N)rW   shieldr   r   s   &r    r   PlayHandle.wait_for_playout  s      nnT^^,,,s   $/-/c                   V ^8  d   QhRR/# )r   r   z Generator[Any, None, PlayHandle]r   )r   s   "r    r!   r     s     ) ); )r#   c                	@   a  R  V 3R llpV! 4       P                  4       # )c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r    r!   *PlayHandle.__await__.<locals>.__annotate__  s     	 	: 	r#   c                 D   <"   S P                  4       G R j  xL
  S #  L5ird   )r   r   s   r    _await_impl)PlayHandle.__await__.<locals>._await_impl  s"     '')))K *s     )	__await__)r(   r  s   f r    r  PlayHandle.__await__  s     	 	 }&&((r#   c                   V ^8  d   QhRR/# r   r   )r   s   "r    r!   r     s     , ,D ,r#   c                	    \         P                  ! \        P                  4      ;_uu_ 4        V P                  P                  R 4       R R R 4       R #   + '       g   i     R # ; ird   )r   r   rW   r  r   r  r   s   &r    r   PlayHandle._mark_playout_done  s:      !:!:;;NN%%d+ <;;;s   AA$	)r   r   N)r,   r-   r.   r/   r^   r   r   r   r  r   r7   r   r#   r    r   r     s%    0%	&-), ,r#   r   c                    V ^8  d   QhRRRR/# )r   r)   r   r   r   r   )r   s   "r    r!   r!     s       0T r#   c               N   "    \        V 4        Rj  xL
  pV5x  K   LDK"  5i)TNr   )r)   r   s   & r    r   r     s)     
1)< 	 	%K	<s   %" "	%"%)6
__future__r   rW   atexitr   enumrk   collections.abcr   r   r   importlib.resourcesr   r   typingr	   r
   numpyr   livekitr   jobr   logr   typesr   r   utilsr   r   	utils.aior   utils.audior   r   r   eventsr   	ExitStackr&   registercloseEnumr   r   r   r:   r9   rR   r   rD   r   r   r   r#   r    <module>r+     s    "      D D . "   !  ) , ' 0 ' *&&( %% &Ftyy F CNN+c14DD* &   D
 D
N
%, %,Pr#   