
    qi!                     X    d dl Z ddlmZ ddlmZ ddlmZmZ d dl	m
Z
mZ  G d d      Zy)	    N   )	FfiHandle)audio_frame_pb2)_ensure_compatible_bufferget_address)AnyUnionc                      e Zd ZdZdddeeeef   dedededee	e
ef   df   d	dfd
Zedededed	d fd       Zedej                   d	d fd       Zd	ej$                  fdZed	e	e
ef   fd       Zed	efd       Zed	efd       Zed	efd       Zed	efd       Zed	efd       Zd	efdZd	e
fdZedefd       Zy)
AudioFramez
    A class that represents a frame of audio data with specific properties such as sample rate,
    number of channels, and samples per channel.

    The format of the audio data is 16-bit signed integers (int16) interleaved by channel.
    N)userdatadatasample_ratenum_channelssamples_per_channelr   returnc                   t        |t              r|j                  d      }t        |      }||z  t	        j
                  t        j                        z  }t        |      }||k  rt        d      |t	        j
                  t        j                        z  dk7  rt        d      || _	        || _
        || _        || _        |i | _        y|| _        y)aG  
        Initialize an AudioFrame instance.

        Args:
            data (Union[bytes, bytearray, memoryview]): The raw audio data, which must be at least
                `num_channels * samples_per_channel * sizeof(int16)` bytes long.
            sample_rate (int): The sample rate of the audio in Hz.
            num_channels (int): The number of audio channels (e.g., 1 for mono, 2 for stereo).
            samples_per_channel (int): The number of samples per channel.

        Raises:
            ValueError: If the length of `data` is smaller than the required size.
        BzIdata length must be >= num_channels * samples_per_channel * sizeof(int16)r   z/data length must be a multiple of sizeof(int16)N)
isinstance
memoryviewcastr   ctypessizeofc_int16len
ValueError_data_sample_rate_num_channels_samples_per_channel	_userdata)selfr   r   r   r   r   min_sizedata_lens           I/opt/pipecat/venv/lib/python3.12/site-packages/livekit/rtc/audio_frame.py__init__zAudioFrame.__init__   s    , dJ'99S>D(."55fnn8UUt9h[  fmmFNN33q8NOO
')$7!'/X    c                     ||z  t        j                  t         j                        z  }t        |      }t	        || ||      S )a  
        Create a new empty AudioFrame instance with specified sample rate, number of channels,
        and samples per channel.

        Args:
            sample_rate (int): The sample rate of the audio in Hz.
            num_channels (int): The number of audio channels (e.g., 1 for mono, 2 for stereo).
            samples_per_channel (int): The number of samples per channel.

        Returns:
            AudioFrame: A new AudioFrame instance with uninitialized (zeroed) data.
        )r   r   r   	bytearrayr   )r   r   r   sizer   s        r$   createzAudioFrame.createL   s<     11FMM&..4QQ$\;NOOr&   
owned_infoc                 l   | j                   }|j                  |j                  z  }t        j                  |z  j                  |j                        }t        |      }t        | j                  j                        j                          t        ||j                  |j                  |j                        S N)infor   r   r   r   from_addressdata_ptrr(   r   handleiddisposer   r   )r+   r.   r)   cdatar   s        r$   _from_owned_infozAudioFrame._from_owned_info^   s      4#;#;;$&44T]]C*##&&'//1$ 0 0$2C2CTE]E]^^r&   c                     t        j                         }t        | j                        |_        | j
                  |_        | j                  |_        | j                  |_        |S r-   )proto_audioAudioFrameBufferInfor   r   r0   r   r   r   )r!   
audio_infos     r$   _proto_infozAudioFrame._proto_infog   sQ     557
)$**5
!%!1!1
"&"3"3
)-)A)A
&r&   c                     | j                   S )zH
        Returns the user data associated with the audio frame.
        )r    r!   s    r$   r   zAudioFrame.userdatao   s    
 ~~r&   c                 h    t        | j                        j                  d      j                  d      S )z
        Returns a memory view of the audio data as 16-bit signed integers.

        Returns:
            memoryview: A memory view of the audio data.
        r   h)r   r   r   r<   s    r$   r   zAudioFrame.datav   s)     $**%**3/44S99r&   c                     | j                   S )zw
        Returns the sample rate of the audio frame.

        Returns:
            int: The sample rate in Hz.
        )r   r<   s    r$   r   zAudioFrame.sample_rate   s        r&   c                     | j                   S )z
        Returns the number of channels in the audio frame.

        Returns:
            int: The number of audio channels (e.g., 1 for mono, 2 for stereo).
        )r   r<   s    r$   r   zAudioFrame.num_channels   s     !!!r&   c                     | j                   S )z
        Returns the number of samples per channel.

        Returns:
            int: The number of samples per channel.
        )r   r<   s    r$   r   zAudioFrame.samples_per_channel   s     (((r&   c                 4    | j                   | j                  z  S )z
        Returns the duration of the audio frame in seconds.

        Returns:
            float: The duration in seconds.
        )r   r   r<   s    r$   durationzAudioFrame.duration   s     ''$*:*:::r&   c                    ddl }ddl}|j                         5 }|j                  |d      5 }|j	                  | j
                         |j                  d       |j                  | j                         |j                  | j                         ddd       |j                         cddd       S # 1 sw Y   "xY w# 1 sw Y   yxY w)z
        Convert the audio frame data to a WAV-formatted byte stream.

        Returns:
            bytes: The audio data encoded in WAV format.
        r   Nwb   )waveioBytesIOopensetnchannelsr   setsampwidthsetframerater   writeframesr   getvalue)r!   rG   rH   wav_filewavs        r$   to_wav_byteszAudioFrame.to_wav_bytes   s     	ZZ\ 	'X8T* ,c  !2!23  #  !1!12

+	, $$&	' 	', ,	' 	's#   B<A#B0B<0B9	5B<<Cc           	      r    d| j                    d| j                   d| j                   d| j                  dd	S )Nzrtc.AudioFrame(sample_rate=z, num_channels=z, samples_per_channel=z, duration=z.3f))r   r   r   rC   r<   s    r$   __repr__zAudioFrame.__repr__   sO    )$*:*:); < --. /##'#;#;"< =c*!-	
r&   _c                    ddl m} dd ldt        ddffd}|j	                  |j                  |j                  |j                  |j                               |j                  |j                               |j                  |j                               |j                  |j                               d      |j                  |      g      |j                  |      |j                  fd      	      S )
Nr   )core_schemavaluer   r   c                     t        | t              r| S t        | t              r| d   } t        | t              r*t        j	                  | d         | d   | d   | d         S t        d      )Nr   r   r   r   r   r   r   r   r   zInvalid type for AudioFrame)r   r   tupledict	b64decode	TypeError)rY   base64s    r$   validate_audio_framezEAudioFrame.__get_pydantic_core_schema__.<locals>.validate_audio_frame   su    %,%'a%&!))%-8 %m 4!&~!6(-.C(D	  9::r&   r[   c                     j                  | j                        j                  d      | j                  | j                  | j
                  dS )Nzutf-8r[   )	b64encoder   decoder   r   r   )instancer`   s    r$   <lambda>z9AudioFrame.__get_pydantic_core_schema__.<locals>.<lambda>   sB    ",,X]];BB7K#+#7#7$,$9$9+3+G+G	" r&   )json_schemapython_schemaserialization)pydantic_corerX   r`   r   json_or_python_schemachain_schemamodel_fields_schemamodel_field
str_schema
int_schema no_info_plain_validator_function$plain_serializer_function_ser_schema)clsrV   rX   ra   r`   s       @r$   __get_pydantic_core_schema__z'AudioFrame.__get_pydantic_core_schema__   s    -	; 	; 	;" 00#0033$/$;$;K<R<R<T$U+6+B+B;CYCYC[+\,7,C,CKDZDZD\,]3>3J3J + 6 6 84		  @@AUV &FFG[\%JJ# 1 
 	
r&   ) __name__
__module____qualname____doc__r	   bytesr(   r   intr]   strr   r%   staticmethodr*   r7   OwnedAudioFrameBufferr5   r8   r:   propertyr   r   r   r   r   floatrC   rR   rU   classmethodrt    r&   r$   r   r      s    15,>E9j01,> ,> 	,>
 !,> S#X,-,> 
,>\ PC Ps P PQ] P P" _[%F%F _< _ _[==  $sCx.   :j : : !S ! ! "c " " )S ) ) ;% ; ;'e '&
# 
 .
c .
 .
r&   r   )r   _ffi_clientr   _protor   r7   _utilsr   r   typingr   r	   r   r   r&   r$   <module>r      s"     " 2 : \
 \
r&   