o
    i^.                     @   s   d dl Z d dlmZmZmZ d dlZd dlmZ d dlmZm	Z
 d dlmZmZ G dd dZdejfd	d
ZG dd dZdededededee dee fddZdejfddZG dd dZdS )    N)IteratorListOptional)Tensor)_get_afilter_descStreamingMediaDecoder)CodecConfigStreamingMediaEncoderc                   @   s.   e Zd ZdZdd ZdefddZdd Zd	S )
_StreamingIOBufferz6Streaming Bytes IO buffer. Data are dropped when read.c                 C   s
   g | _ d S N)_buffer)self r   K/home/ubuntu/.local/lib/python3.10/site-packages/torchaudio/io/_effector.py__init__   s   
z_StreamingIOBuffer.__init__bc                 C   s   |r| j | t|S r   )r   appendlen)r   r   r   r   r   write   s   z_StreamingIOBuffer.writec                 C   sV   | j sdS t| j d |kr| j dS | j d d| }| j d |d | j d< |S )zMPop the oldest byte string. It does not necessary return the requested amount    r   N)r   r   pop)r   nretr   r   r   r      s   z_StreamingIOBuffer.popN)__name__
__module____qualname____doc__r   bytesr   r   r   r   r   r   r
      s
    r
   dtypec              
   C   J   t jdt jdt jdt jdt jdi}| |vr!td|  d|  ||  S )Nu8s16s32fltdblUnsupported dtype is provided . Supported dtypes are: torchuint8int16int32float32float64
ValueErrorkeysr   typesr   r   r   _get_sample_fmt!   s   r2   c                   @   sF   e Zd ZdZdededededee dee defd	d
Z	dd Z
dS )_AudioStreamingEncoderz3Given a waveform, encode on-demand and return bytessrcsample_rateeffectmuxerencodercodec_configframes_per_chunkc                 C   s\   || _ t | _t| j|d| _| jj|d|t|j|||d | j	  || _
d| _d S N)format   )num_channelsr5   r<   r8   filter_descr9   r   )r4   r
   bufferStreamWriterwriteradd_audio_streamsizer2   r   openfpci_iter)r   r4   r5   r6   r7   r8   r9   r:   r   r   r   r   1   s   


z_AudioStreamingEncoder.__init__c                 C   s   | j jsA| jdkrA| jd| j| j| j| j   |  j| j7  _| j| jdkr8| j  | j	  d| _| j jsA| jdks	| j 
|S )Nr   )r@   r   rG   rB   write_audio_chunkr4   rF   rD   flushcloser   )r   r   r   r   r   readN   s   "

z_AudioStreamingEncoder.readN)r   r   r   r   r   intstrr   r   r   rL   r   r   r   r   r3   .   s$    
r3   r4   r5   r6   r7   r8   r9   c                 C   sx   t  }t||d}|j| d|t| j|||d |  |d|  W d    n1 s0w   Y  |	d |S r;   )
ioBytesIOrA   rC   rD   r2   r   rE   rI   seek)r4   r5   r6   r7   r8   r9   r@   rB   r   r   r   _encodeY   s   

rR   c              
   C   r   )Nr    s16les32lef32lef64ler%   r&   r'   r0   r   r   r   
_get_muxerq   s   rW   c                   @   s   e Zd ZdZ		ddddddee dee dee dee d	ef
d
dZdddZ	dde
dedee de
fddZ	dde
dededee dee
 f
ddZdS )AudioEffectora  Apply various filters and/or codecs to waveforms.

    .. versionadded:: 2.1

    Args:
        effect (str or None, optional): Filter expressions or ``None`` to apply no filter.
            See https://ffmpeg.org/ffmpeg-filters.html#Audio-Filters for the
            details of filter syntax.

        format (str or None, optional): When provided, encode the audio into the
            corresponding format. Default: ``None``.

        encoder (str or None, optional): When provided, override the encoder used
            by the ``format``. Default: ``None``.

        codec_config (CodecConfig or None, optional): When provided, configure the encoding codec.
            Should be provided in conjunction with ``format`` option.

        pad_end (bool, optional): When enabled, and if the waveform becomes shorter after applying
            effects/codec, then pad the end with silence.

    Example - Basic usage
        To use ``AudioEffector``, first instantiate it with a set of
        ``effect`` and ``format``.

        >>> # instantiate the effector
        >>> effector = AudioEffector(effect=..., format=...)

        Then, use :py:meth:`~AudioEffector.apply` or :py:meth:`~AudioEffector.stream`
        method to apply them.

        >>> # Apply the effect to the whole waveform
        >>> applied = effector.apply(waveform, sample_rate)

        >>> # Apply the effect chunk-by-chunk
        >>> for chunk in effector.stream(waveform, sample_rate):
        >>>    ...

    Example - Applying effects
        Please refer to
        https://ffmpeg.org/ffmpeg-filters.html#Filtergraph-description
        for the overview of filter description, and
        https://ffmpeg.org/ffmpeg-filters.html#toc-Audio-Filters
        for the list of available filters.

        Tempo - https://ffmpeg.org/ffmpeg-filters.html#atempo

        >>> AudioEffector(effect="atempo=1.5")

        Echo - https://ffmpeg.org/ffmpeg-filters.html#aecho

        >>> AudioEffector(effect="aecho=0.8:0.88:60:0.4")

        Flanger - https://ffmpeg.org/ffmpeg-filters.html#flanger

        >>> AudioEffector(effect="aflanger")

        Vibrato - https://ffmpeg.org/ffmpeg-filters.html#vibrato

        >>> AudioEffector(effect="vibrato")

        Tremolo - https://ffmpeg.org/ffmpeg-filters.html#tremolo

        >>> AudioEffector(effect="vibrato")

        You can also apply multiple effects at once.

        >>> AudioEffector(effect="")

    Example - Applying codec
        One can apply codec using ``format`` argument. ``format`` can be
        audio format or container format. If the container format supports
        multiple encoders, you can specify it with ``encoder`` argument.

        Wav format
        (no compression is applied but samples are converted to
        16-bit signed integer)

        >>> AudioEffector(format="wav")

        Ogg format with default encoder

        >>> AudioEffector(format="ogg")

        Ogg format with vorbis

        >>> AudioEffector(format="ogg", encoder="vorbis")

        Ogg format with opus

        >>> AudioEffector(format="ogg", encoder="opus")

        Webm format with opus

        >>> AudioEffector(format="webm", encoder="opus")

    Example - Applying codec with configuration
        Reference: https://trac.ffmpeg.org/wiki/Encode/MP3

        MP3 with default config

        >>> AudioEffector(format="mp3")

        MP3 with variable bitrate

        >>> AudioEffector(format="mp3", codec_config=CodecConfig(qscale=5))

        MP3 with constant bitrate

        >>> AudioEffector(format="mp3", codec_config=CodecConfig(bit_rate=32_000))
    NT)r8   r9   pad_endr6   r<   r8   r9   rY   c                C   sB   |d u r|d us|d urt d|| _|| _|| _|| _|| _d S )NzM`encoder` and/or `condec_config` opions are provided without `format` option.)r.   r6   r<   r8   r9   rY   )r   r6   r<   r8   r9   rY   r   r   r   r      s   	
zAudioEffector.__init__c                 C   s   |j \}}| jd ur| j}| j}i }	| jdkr| | d}	nt|j}d }| | d}	|d u r=t||| j||| j}
nt||| j||| j|}
|d u rO|n|}t	|t
|j|}| jrd| d| }t|
||	d}|j|ppdd|d |S )Nmulaw)r5   channelsz,apad=whole_len=)r<   optionrH   )r?   )shaper<   r8   rW   r   rR   r6   r9   r3   r   r2   rY   StreamReaderrC   )r   waveformr5   output_sample_rater:   
num_framesr>   r7   r8   r\   r4   	output_srr?   readerr   r   r   _get_reader  s.   



zAudioEffector._get_readerr_   r5   r`   returnc                 C   sR   |j dkrtd|j  | dkr|S | |||}|  | \}t|S )a  Apply the effect and/or codecs to the whole tensor.

        Args:
            waveform (Tensor): The input waveform. Shape: ``(time, channel)``
            sample_rate (int): Sample rate of the input waveform.
            output_sample_rate (int or None, optional): Output sample rate.
                If provided, override the output sample rate.
                Otherwise, the resulting tensor is resampled to have
                the same sample rate as the input.
                Default: ``None``.

        Returns:
            Tensor:
                Resulting Tensor. Shape: ``(time, channel)``. The number of frames
                could be different from that of the input.
           -Expected the input waveform to be 2D. Found: r   )ndimr.   numelrd   process_all_packets
pop_chunksr   )r   r_   r5   r`   rc   appliedr   r   r   apply"  s   

zAudioEffector.applyr:   c                 c   sZ    |j dkrtd|j  | dkr|S | ||||}| D ]\}t|V  q"dS )aZ  Apply the effect and/or codecs to the given tensor chunk by chunk.

        Args:
            waveform (Tensor): The input waveform. Shape: ``(time, channel)``
            sample_rate (int): Sample rate of the waveform.
            frames_per_chunk (int): The number of frames to return at a time.
            output_sample_rate (int or None, optional): Output sample rate.
                If provided, override the output sample rate.
                Otherwise, the resulting tensor is resampled to have
                the same sample rate as the input.
                Default: ``None``.

        Returns:
            Iterator[Tensor]:
                Series of processed chunks. Shape: ``(time, channel)``, where the
                the number of frames matches ``frames_per_chunk`` except the
                last chunk, which could be shorter.
        rf   rg   r   N)rh   r.   ri   rd   streamr   )r   r_   r5   r:   r`   rc   rl   r   r   r   rn   >  s   
zAudioEffector.stream)NNr   )r   r   r   r   r   rN   r   boolr   rd   r   rM   rm   r   rn   r   r   r   r   rX      sB    r

  rX   )rO   typingr   r   r   r(   r   !torio.io._streaming_media_decoderr   r   r^   !torio.io._streaming_media_encoderr   r	   rA   r
   r   r2   r3   rM   rN   rR   rW   rX   r   r   r   r   <module>   s0    +
