U
    ,:%e.                     @   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ejd	d
dZG dd dZeeeeee ee dddZejd	ddZG dd dZdS )    N)IteratorListOptional)Tensor   )_get_afilter_descStreamReader)CodecConfigStreamWriterc                   @   s.   e Zd ZdZdd Zed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   V/var/www/html/Darija-Ai-API/env/lib/python3.8/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   sJ   t jdt jdt jdt jdt jdi}| |krBtd|  d|  ||  S )Nu8Zs16Zs32ZfltZdblUnsupported dtype is provided . Supported dtypes are: torchZuint8Zint16Zint32Zfloat32Zfloat64
ValueErrorkeysr   typesr   r   r   _get_sample_fmt!   s         r)   c                   @   s:   e Zd ZdZeeeeee ee ed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)formatr   )num_channelsr,   r3   r/   filter_descr0   r   )r+   r   bufferr
   writeradd_audio_streamsizer)   r   openfpci_iter)r   r+   r,   r-   r.   r/   r0   r1   r   r   r   r   1   s    

z_AudioStreamingEncoder.__init__c                 C   s~   | j jsr| jdkrr| jd| j| j| j| j   |  j| j7  _| j| jdkr | j  | j	  d| _q | j 
|S )Nr   )r6   r   r<   r7   write_audio_chunkr+   r;   r9   flushcloser   )r   r   r   r   r   readN   s    "

z_AudioStreamingEncoder.readN)r   r   r   r   r   intstrr   r	   r   rA   r   r   r   r   r*   .   s   r*   )r+   r,   r-   r.   r/   r0   c              	   C   sd   t  }t||d}|j| d|t| j|||d |  |d|  W 5 Q R X |	d |S r2   )
ioBytesIOr
   r8   r9   r)   r   r:   r>   seek)r+   r,   r-   r.   r/   r0   r6   r7   r   r   r   _encodeY   s    

rG   c              
   C   sJ   t jdt jdt jdt jdt jdi}| |krBtd|  d|  ||  S )Nr    Zs16leZs32leZf32leZf64ler!   r"   r#   r'   r   r   r   
_get_muxerq   s         rH   c                   @   s   e Zd ZdZdddddee ee ee ee edddZddd	Z	de
eee e
d
ddZde
eeee ee
 d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)r/   r0   pad_end)r-   r3   r/   r0   rJ   c                C   sB   |d kr |d k	s|d k	r t d|| _|| _|| _|| _|| _d S )NzM`encoder` and/or `condec_config` opions are provided without `format` option.)r%   r-   r3   r/   r0   rJ   )r   r-   r3   r/   r0   rJ   r   r   r   r      s    	zAudioEffector.__init__c                 C   s   |j \}}| jd k	r>| j}| j}i }	| jdkrZ| | d}	nt|j}d }| | d}	|d krzt||| j||| j}
nt||| j||| j|}
|d kr|n|}t	|t
|j|}| jr| d| }t|
||	d}|j|pdd|d |S )NZmulaw)r,   Zchannelsz,apad=whole_len=)r3   optionr=   )r5   )shaper3   r/   rH   r   rG   r-   r0   r*   r   r)   rJ   r   r8   )r   waveformr,   output_sample_rater1   Z
num_framesr4   r.   r/   rK   r+   Z	output_srr5   readerr   r   r   _get_reader  s8    



      zAudioEffector._get_reader)rM   r,   rN   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%   numelrP   Zprocess_all_packetsZ
pop_chunksr   )r   rM   r,   rN   rO   appliedr   r   r   apply"  s    

zAudioEffector.apply)rM   r,   r1   rN   rQ   c                 c   sX   |j dkrtd|j  | dkr*|S | ||||}| D ]\}t|V  qBd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.
        rR   rS   r   N)rT   r%   rU   rP   streamr   )r   rM   r,   r1   rN   rO   rV   r   r   r   rX   >  s    
zAudioEffector.stream)NN)N)N)N)r   r   r   r   r   rC   r	   boolr   rP   r   rB   rW   r   rX   r   r   r   r   rI      s0   r  
     rI   )rD   typingr   r   r   r$   r   _stream_readerr   r   _stream_writerr	   r
   r   r   r)   r*   rB   rC   rG   rH   rI   r   r   r   r   <module>   s"   ,