o
    8wi!                     @   sb   d dl mZ d dlmZmZ d dlZd dlZd dlmZ d dlZeeee	f Z
	 G dd dZdS )    )Path)TextUnionN)Tensorc                	       s   e Zd ZdZededefddZededefddZ	ed	e
eef defd
dZdedefddZddedef fddZdededefddZ	ddedededefddZ  ZS )AudiouI  Audio IO with on-the-fly resampling

    Parameters
    ----------
    sample_rate: int
        Target sample rate.
    mono : int, optional
        Convert multi-channel to mono. Defaults to True.

    Usage
    -----
    >>> audio = Audio(sample_rate=16000)
    >>> samples = audio("/path/to/audio.wav")

    # on-the-fly resampling
    >>> original_sample_rate = 44100
    >>> two_seconds_stereo = torch.rand(2, 2 * original_sample_rate)
    >>> samples = audio({"samples": two_seconds_stereo, "sample_rate": original_sample_rate})
    >>> assert samples.shape[1] == 2 * 16000
    filereturnc                 C   s|   t | tr<d| v r2| d }t|jdks|jd |jd kr"td| dd }|d u r0tddS d	| v r8dS td
dS )Nsamples   r      z='samples' must be provided as a (channel, time) torch.Tensor.sample_ratez4'samples' must be provided with their 'sample_rate'.Taudioz1either 'audio' or 'samples' key must be provided.)
isinstancedictlenshape
ValueErrorget)r   r	   r    r   [/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torch_audiomentations/utils/io.pyis_valid.   s"   
"zAudio.is_validr	   c                 C   s"   |   jddd }| |d  S )a  Power-normalize samples

        Parameters
        ----------
        samples : (..., time) Tensor
            Single (or multichannel) samples or batch of samples

        Returns
        -------
        samples: (..., time) Tensor
            Power-normalized samples
        Tdimkeepdimg:0yE>)squaremeansqrt)r	   rmsr   r   r   rms_normalizeH   s   zAudio.rms_normalize	file_pathc                 C   sJ   t t| }t|tu r|\}}|j}|j}||fS |j}|j}||fS )z"Return (num_samples, sample_rate).)	
torchaudioinfostrtypetuplelengthrate
num_framesr   )r    r"   sieinum_samplesr   r   r   r   get_audio_metadataY   s   zAudio.get_audio_metadatac                 C   sj   |  | t|tr$d|v r|d jd }|d }n| |d \}}n| |\}}t|| j | S )zTNumber of samples (in target sample rate)

        :param file: audio file

        r	   r   r   r   )r   r   r   r   r,   mathceilr   )selfr   r+   r   r   r   r   get_num_samplesh   s   


zAudio.get_num_samplesTr   monoc                    s   t    || _|| _d S )N)super__init__r   r1   )r/   r   r1   	__class__r   r   r3      s   

zAudio.__init__c                 C   sB   | j r|jd dkr|jddd}| j|krtj||| j}|S )a2  Downmix and resample

        Parameters
        ----------
        samples : (channel, time) Tensor
            Samples.
        sample_rate : int
            Original sample rate.

        Returns
        -------
        samples : (channel, time) Tensor
            Remixed and resampled samples
        r   r   Tr   )r1   r   r   r   r!   
functionalresample)r/   r	   r   r   r   r   downmix_and_resample   s   
zAudio.downmix_and_resampler   Nsample_offsetr+   c                 C   s  |  | d}t|tr8d|v r$|d }|d }|jd }|dd}n!t|d }| |\}}|dd}nt|}| |\}}d}t|| | j }	|du rW||	 }
n	t|| | j }
|	|
 |krit	 |du rzt
j||	|
d\}}W n ty   tdw |dd|	|	|
 f }|dur||d |ddf }| ||}|dur|jd	 |kr|ddd|f }|S |jd	 |k r||jd	  }tjj|d
|f}|S )a  

        Parameters
        ----------
        file : AudioFile
            Audio file.
        sample_offset : int, optional
            Start loading at this `sample_offset` sample. Defaults ot 0.
        num_samples : int, optional
            Load that many samples. Defaults to load up to the end of the file.

        Returns
        -------
        samples : (time, channel) torch.Tensor
            Samples

        Nr	   r   r   channelr   )frame_offsetr(   z~It looks like you are using an unsupported version of torchaudio. If you have 0.6 or older, please upgrade to a newer version.r   r   )r   r   r   r   r   r#   r,   roundr   r   r!   load	TypeError	Exceptionr8   torchnnr6   pad)r/   r   r9   r+   original_samplesoriginal_sample_rateoriginal_total_num_samplesr:   
audio_pathoriginal_sample_offsetoriginal_num_samplesoriginal_data_resultdiffr   r   r   __call__   sn   



zAudio.__call__)T)r   N)__name__
__module____qualname____doc__staticmethod	AudioFileboolr   r   r   r   r#   r   r%   r,   intr0   r3   r8   rM   __classcell__r   r   r4   r   r      s*    r   )pathlibr   typingr   r   r@   r!   r   r-   r   rS   r   r   r   r   r   <module>   s    