§
    ~ŠtjF  ã                  ój   — d Z ddlmZ ddlZddlZddlZddlZdZddd„Zdd„Z	dd„Z
d d„Zedœd!d„ZdS )"uÉ  WAV reconstruction for the voice integrations.

* ``pcm_to_wav`` â€” wrap already-merged PCM16 bytes in a WAV container. Used by the
  Pipecat processor (whose ``AudioBufferProcessor`` emits merged stereo audio).
* ``build_stereo_session_wav`` â€” reconstruct one stereo conversation WAV from the
  timestamped PCM16 chunks each side recorded (L=user, R=agent), laid out at
  natural play time so bursts don't overlap. Used by the Track-B ``EventSession``.
é    )ÚannotationsNiX  é   ÚpcmÚbytesÚsample_rateÚintÚnum_channelsÚreturnc                óZ  — | sdS t          j        ¦   «         }t          j        |d¦  «        5 }|                     |¦  «         |                     d¦  «         |                     |¦  «         |                     | ¦  «         ddd¦  «         n# 1 swxY w Y   |                     ¦   «         S )zÞWrap raw PCM16 bytes in a WAV container.

    For already-merged PCM (e.g. the output of Pipecat's ``AudioBufferProcessor``,
    where ``num_channels=2`` is user-left / bot-right). Returns ``b""`` for empty
    input.
    ó    Úwbé   N)	ÚioÚBytesIOÚwaveÚopenÚsetnchannelsÚsetsampwidthÚsetframerateÚwriteframesÚgetvalue)r   r   r	   ÚbufÚwfs        ú]/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langsmith/_internal/voice/audio.pyÚ
pcm_to_wavr      sØ   € ð ð ØˆsÝ
Œ*‰,Œ,€CÝ	Œ�3˜Ñ	Ô	ð  Ø
�Š˜Ñ%Ô%Ð%Ø
�Š˜ÑÔÐØ
�Š˜Ñ$Ô$Ð$Ø
�Š�sÑÔÐð	ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð
 �<Š<‰>Œ>Ðs   ­ABÂBÂBÚchunksúlist[tuple[float, bytes]]c                óÌ   — g }d}t          | ¦  «        D ]O\  }\  }}|dk    r|nt          ||¦  «        }|                     ||f¦  «         |t          |¦  «        dz  |z  z  }ŒP|S )u]  Rewrite receipt timestamps into natural-play timestamps.

    Receipt times reflect when bytes arrived from the source, not when they
    play. The agent channel especially arrives in bursts faster than realtime â€”
    multiple chunks can land within a few ms of each other, and placing them at
    receipt time makes them overlap and overwrite each other (you hear scrambled
    tail-ends). The correct natural play time for a chunk is the LATER of where
    the previous chunk ended and when this chunk arrived, which preserves real
    gaps between bursts and keeps consecutive bursts contiguous.
    ç        r   r   )Ú	enumerateÚmaxÚappendÚlen)r   r   ÚoutÚcur_timeÚiÚt_recvÚdatas          r   Ú_layout_chunks_to_play_timer)   &   s€   € ð &(€CØ€HÝ& vÑ.Ô.ð 3ð 3Ñˆ‰>ˆF�DØ !šV˜V�6�6­¨X°vÑ)>Ô)>ˆØ�
Š
�H˜dÐ#Ñ$Ô$Ð$Ø•S˜‘Y”Y !‘^ {Ñ2Ñ2ˆˆØ€Jr   ÚtÚfloatr(   c                ó2   — | t          |¦  «        dz  |z  z   S )Nr   )r#   )r*   r(   r   s      r   Ú
_chunk_endr-   <   s   € Ø•�D‘	”	˜Q‘ +Ñ-Ñ-Ð-r   Úuser_chunksÚagent_chunksÚmax_duration_secondsúfloat | NoneÚboolc                óè   ‡— |€dS t          | ‰¦  «        }t          |‰¦  «        }t          ˆfd„|D ¦   «         d¬¦  «        }t          ˆfd„|D ¦   «         d¬¦  «        }t          ||¦  «        |k    S )z@Return whether natural-play WAV layout exceeds the duration cap.NFc              3  ó@   •K  — | ]\  }}t          ||‰¦  «        V — Œd S ©N©r-   ©Ú.0r*   Údr   s      €r   ú	<genexpr>z3session_wav_exceeds_duration_cap.<locals>.<genexpr>K   ó3   øè è € ÐCÐC±d°a¸•J˜q ! [Ñ1Ô1ÐCÐCÐCÐCÐCÐCr   r   ©Údefaultc              3  ó@   •K  — | ]\  }}t          ||‰¦  «        V — Œd S r5   r6   r7   s      €r   r:   z3session_wav_exceeds_duration_cap.<locals>.<genexpr>L   ó3   øè è € ÐEÐE±t°q¸!•Z  1 kÑ2Ô2ÐEÐEÐEÐEÐEÐEr   )r)   r!   )r.   r/   r   r0   ÚuserÚagentÚuser_endÚ	agent_ends     `     r   Ú session_wav_exceeds_duration_caprD   @   s’   ø€ ð Ð#ØˆuÝ& {°KÑ@Ô@€DÝ'¨°kÑBÔB€EÝÐCÐCÐCÐC¸dÐCÑCÔCÈSÐQÑQÔQ€HÝÐEÐEÐEÐE¸uÐEÑEÔEÈsÐSÑSÔS€IÝˆx˜Ñ#Ô#Ð&:Ò:Ð:r   )r0   c               ó¾  ‡‡— | s|sdS t          | ‰¦  «        }t          |‰¦  «        }t          ˆfd„|D ¦   «         d¬¦  «        }t          ˆfd„|D ¦   «         d¬¦  «        }t          t          j        t          ||¦  «        ‰z  ¦  «        ¦  «        Š|�4t          t          j        |‰z  ¦  «        ¦  «        }t          ‰|¦  «        Š‰dk    rdS dˆˆfd„}	 |	|¦  «        }
 |	|¦  «        }t          j        dt          d‰z  ¦  «        ¦  «        }|
|ddd…<   ||ddd…<   t          j	        ¦   «         }t          j        |d¦  «        5 }|                     d¦  «         |                     d¦  «         |                     ‰¦  «         |                     |                     ¦   «         ¦  «         ddd¦  «         n# 1 swxY w Y   |                     ¦   «         S )aj  Reconstruct a duration-capped stereo WAV from timestamped PCM16 chunks.

    Left channel = user, right channel = agent. Both channels are laid out at
    natural play time (see ``_layout_chunks_to_play_time``). Gaps between bursts
    are silence; overlap between user and agent (during a barge-in) is preserved
    because they live on different channels.
    r   c              3  ó@   •K  — | ]\  }}t          ||‰¦  «        V — Œd S r5   r6   r7   s      €r   r:   z+build_stereo_session_wav.<locals>.<genexpr>d   r;   r   r   r<   c              3  ó@   •K  — | ]\  }}t          ||‰¦  «        V — Œd S r5   r6   r7   s      €r   r:   z+build_stereo_session_wav.<locals>.<genexpr>e   r?   r   Nr   r   r   r
   úarray.arrayc           
     óV  •— t          j         dt          d‰z  ¦  «        ¦  «        }| D ]\  }}t          |‰z  ¦  «        }t          j         d|d dt          |¦  «        dz  z  …         ¦  «        }t	          t          |¦  «        ‰|z
  ¦  «        }|dk    r|d |…         ||||z   …<   Œ€|S )NÚhr   r   )Úarrayr   r   r#   Úmin)	r   Úchanr*   r(   ÚoffsetÚsamplesÚnr   Útotal_sampless	          €€r   Úmono_channelz.build_stereo_session_wav.<locals>.mono_channelm   s¶   ø€ õ Œ{˜3¥ a¨-Ñ&7Ñ 8Ô 8Ñ9Ô9ˆØð 	8ð 	8‰GˆAˆtÝ˜˜[™Ñ)Ô)ˆFÝ”k # tÐ,B¨aµ3°t±9´9À±>Ñ.BÐ,BÔ'CÑDÔDˆGÝ•C˜‘L”L -°&Ñ"8Ñ9Ô9ˆAØ�1ŠuˆuØ,3°B°Q°B¬K��V˜f q™jÐ(Ñ)øØˆr   rJ   é   r   r   r   )r   r   r
   rH   )r)   r!   r   ÚmathÚceilrL   rK   r   r   r   r   r   r   r   r   r   Útobytesr   )r.   r/   r   r0   r@   rA   rB   rC   Úmax_samplesrR   ÚleftÚrightÚstereoÚwav_ior   rQ   s     `            @r   Úbuild_stereo_session_wavr\   P   sB  øø€ ð ð ˜|ð Øˆså& {°KÑ@Ô@€DÝ'¨°kÑBÔB€EåÐCÐCÐCÐC¸dÐCÑCÔCÈSÐQÑQÔQ€HÝÐEÐEÐEÐE¸uÐEÑEÔEÈsÐSÑSÔS€IÝ�œ	¥# h°	Ñ":Ô":¸[Ñ"HÑIÔIÑJÔJ€MØÐ'Ý�$œ)Ð$8¸;Ñ$FÑGÔGÑHÔHˆÝ˜M¨;Ñ7Ô7ˆØ˜ÒÐØˆsðð ð ð ð ð ð ð ˆ<˜ÑÔ€DØˆL˜ÑÔ€Eõ Œ[˜�e A¨Ñ$5Ñ6Ô6Ñ7Ô7€FØ€Fˆ1ˆ4ˆaˆ4�LØ€Fˆ1ˆ4ˆaˆ4�LåŒZ‰\Œ\€FÝ	Œ�6˜4Ñ	 Ô	 ð ) BØ
�Š˜ÑÔÐØ
�Š˜ÑÔÐØ
�Š˜Ñ$Ô$Ð$Ø
�Š�v—~’~Ñ'Ô'Ñ(Ô(Ð(ð	)ð )ð )ñ )ô )ð )ð )ð )ð )ð )ð )øøøð )ð )ð )ð )ð
 �?Š?ÑÔÐs   ÅA'G Ç GÇG)r   )r   r   r   r   r	   r   r
   r   )r   r   r   r   r
   r   )r*   r+   r(   r   r   r   r
   r+   )
r.   r   r/   r   r   r   r0   r1   r
   r2   )
r.   r   r/   r   r   r   r0   r1   r
   r   )Ú__doc__Ú
__future__r   rK   r   rT   r   ÚDEFAULT_MAX_AUDIO_SECONDSr   r)   r-   rD   r\   © r   r   ú<module>ra      sÐ   ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø €€€Ø €€€à#Ð ðð ð ð ð ð$ð ð ð ð,.ð .ð .ð .ð;ð ;ð ;ð ;ð* *Cð9ð 9ð 9ð 9ð 9ð 9ð 9ð 9r   