
    qi                     \   d Z ddlZddl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 ddlmZ dd	lmZ dd
lmZmZ 	 ddlZ G d de      Z G d de      Z G d de      Z G d de      Zy# e$ r7Z ej0                  de         ej0                  d        ede       dZ[ww xY w)zLocal audio transport implementation for Pipecat.

This module provides a local audio transport that uses PyAudio for real-time
audio input and output through the system's default audio devices.
    N)ThreadPoolExecutor)Optional)logger)InputAudioRawFrameOutputAudioRawFrame
StartFrame)FrameProcessor)BaseInputTransport)BaseOutputTransport)BaseTransportTransportParamszException: z~In order to use local audio, you need to `pip install pipecat-ai[local]`. On MacOS, you also need to `brew install portaudio`.zMissing module: c                   :    e Zd ZU dZdZee   ed<   dZee   ed<   y)LocalAudioTransportParamszConfiguration parameters for local audio transport.

    Parameters:
        input_device_index: PyAudio device index for audio input. If None, uses default.
        output_device_index: PyAudio device index for audio output. If None, uses default.
    Ninput_device_indexoutput_device_index)	__name__
__module____qualname____doc__r   r   int__annotations__r        P/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/transports/local/audio.pyr   r   #   s'     )-,)-#-r   r   c                   l     e Zd ZU dZeed<   dej                  def fdZde	f fdZ
 fdZd	 Z xZS )
LocalAudioInputTransportzLocal audio input transport using PyAudio.

    Captures audio from the system's audio input device and converts it to
    InputAudioRawFrame objects for processing in the pipeline.
    _paramspy_audioparamsc                 N    t         |   |       || _        d| _        d| _        y)zInitialize the local audio input transport.

        Args:
            py_audio: PyAudio instance for audio device management.
            params: Transport configuration parameters.
        Nr   )super__init__	_py_audio
_in_stream_sample_rateselfr   r   	__class__s      r   r"   z!LocalAudioInputTransport.__init__8   s(     	 !r   framec           	      F  K   t         |   |       d{    | j                  ry| j                  j                  xs |j                  | _        t        | j
                  dz        dz  }| j                  j                  | j                  j                  d      | j                  j                  | j
                  || j                  d| j                  j                        | _        | j                  j                          | j                  |       d{    y7 7 w)z~Start the audio input stream.

        Args:
            frame: The start frame containing initialization parameters.
        Nd      T)formatchannelsrateframes_per_bufferstream_callbackinputr   )r!   startr$   r   audio_in_sample_rater%   r   r#   openget_format_from_widthaudio_in_channels_audio_in_callbackr   start_streamset_transport_ready)r'   r)   
num_framesr(   s      r   r3   zLocalAudioInputTransport.startE   s      gmE"""?? LL==[A[A[**S01A5
..-->>77:\\33""( 33#||>> . 
 	$$&&&u---' 	#& 	.s"   D!DC?D!DD!D!c                    K   t         |           d{    | j                  r<| j                  j                          | j                  j	                          d| _        yy7 Mw)z(Stop and cleanup the audio input stream.N)r!   cleanupr$   stop_streamcloser'   r(   s    r   r=   z LocalAudioInputTransport.cleanup`   sO     go??OO'')OO!!#"DO  	    A%A#AA%c                     t        || j                  | j                  j                        }t	        j
                  | j                  |      | j                                dt        j                  fS )z+Callback function for PyAudio input stream.)audiosample_ratenum_channelsN)
r   r%   r   r7   asynciorun_coroutine_threadsafepush_audio_frameget_event_looppyaudio
paContinue)r'   in_dataframe_count	time_infostatusr)   s         r   r8   z+LocalAudioInputTransport._audio_in_callbackh   s\    "))77
 	(()>)>u)EtGZGZG\]g(())r   )r   r   r   r   r   r   rJ   PyAudior"   r   r3   r=   r8   __classcell__r(   s   @r   r   r   /   s>     '& :S . .6#
*r   r   c                   v     e Zd ZU dZeed<   dej                  def fdZde	f fdZ
 fdZded	efd
Z xZS )LocalAudioOutputTransportzLocal audio output transport using PyAudio.

    Plays audio frames through the system's audio output device by converting
    OutputAudioRawFrame objects to playable audio data.
    r   r   r   c                 p    t         |   |       || _        d| _        d| _        t        d      | _        y)zInitialize the local audio output transport.

        Args:
            py_audio: PyAudio instance for audio device management.
            params: Transport configuration parameters.
        Nr      )max_workers)r!   r"   r#   _out_streamr%   r   	_executorr&   s      r   r"   z"LocalAudioOutputTransport.__init__~   s7     	 ! ,:r   r)   c                   K   t         |   |       d{    | j                  ry| j                  j                  xs |j                  | _        | j                  j                  | j                  j                  d      | j                  j                  | j
                  d| j                  j                        | _        | j                  j                          | j                  |       d{    y7 7 w)zStart the audio output stream.

        Args:
            frame: The start frame containing initialization parameters.
        Nr,   T)r-   r.   r/   outputr   )r!   r3   rX   r   audio_out_sample_rater%   r#   r5   r6   audio_out_channelsr   r9   r:   )r'   r)   r(   s     r   r3   zLocalAudioOutputTransport.start   s      gmE""" LL>>]%B]B]>>..>>77:\\44"" $ @ @ / 
 	%%'&&u---! 	#  	.s"   C9C5CC9/C70C97C9c                    K   t         |           d{    | j                  r<| j                  j                          | j                  j	                          d| _        yy7 Mw)z)Stop and cleanup the audio output stream.N)r!   r=   rX   r>   r?   r@   s    r   r=   z!LocalAudioOutputTransport.cleanup   sV     go((*""$#D  	 rA   returnc                    K   | j                   rR| j                         j                  | j                  | j                   j                  |j
                         d{    yy7 w)zWrite an audio frame to the output stream.

        Args:
            frame: The audio frame to write to the output device.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        NTF)rX   rI   run_in_executorrY   writerC   )r'   r)   s     r   write_audio_framez+LocalAudioOutputTransport.write_audio_frame   sZ      %%'77 0 0 6 6   	s   AA$A"A$)r   r   r   r   r   r   rJ   rP   r"   r   r3   r=   r   boolrc   rQ   rR   s   @r   rT   rT   u   sM     '&; ;:S ;". .0$-@ T r   rT   c                   @     e Zd ZdZdef fdZdefdZdefdZ xZ	S )LocalAudioTransportzComplete local audio transport with input and output capabilities.

    Provides a unified interface for local audio I/O using PyAudio, supporting
    both audio capture and playback through the system's audio devices.
    r   c                 ~    t         |           || _        t        j                         | _        d| _        d| _        y)zuInitialize the local audio transport.

        Args:
            params: Transport configuration parameters.
        N)r!   r"   r   rJ   rP   _pyaudio_input_output)r'   r   r(   s     r   r"   zLocalAudioTransport.__init__   s3     	):><@r   r_   c                 |    | j                   s%t        | j                  | j                        | _         | j                   S )z}Get the input frame processor for this transport.

        Returns:
            The audio input transport processor.
        )ri   r   rh   r   r'   s    r   r2   zLocalAudioTransport.input   s+     {{24==$,,ODK{{r   c                 |    | j                   s%t        | j                  | j                        | _         | j                   S )zGet the output frame processor for this transport.

        Returns:
            The audio output transport processor.
        )rj   rT   rh   r   rl   s    r   r[   zLocalAudioTransport.output   s+     ||4T]]DLLQDL||r   )
r   r   r   r   r   r"   r	   r2   r[   rQ   rR   s   @r   rf   rf      s/    A8 A"~  r   rf   )r   rF   concurrent.futuresr   typingr   logurur   pipecat.frames.framesr   r   r   "pipecat.processors.frame_processorr	   pipecat.transports.base_inputr
   pipecat.transports.base_outputr   !pipecat.transports.base_transportr   r   rJ   ModuleNotFoundErroreerror	Exceptionr   r   rT   rf   r   r   r   <module>rz      s     1   U U = < > L,	. 	.C*1 C*LH 3 HV*- *K  ,FLL;qc"#FLL 	I &qc*
++,s   A/ /B+42B&&B+