o
    %ݫi-                     @   sh   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
 G dd deZG dd	 d	eZdS )
aR   Specifies the inference interfaces for Audio Classification modules.

Authors:
 * Aku Rouhe 2021
 * Peter Plantinga 2021
 * Loren Lugosch 2020
 * Mirco Ravanelli 2020
 * Titouan Parcollet 2021
 * Abdel Heba 2021
 * Andreas Nautsch 2022, 2023
 * Pooneh Mousavi 2023
 * Sylvain de Langen 2023
 * Adel Moumen 2023
 * Pradnya Kandarkar 2023
    N)
Pretrained)
split_path)LocalStrategyfetchc                   @   s>   e Zd ZdZg dZdddZdddZd	d
 ZdddZdS )EncoderClassifiera9  A ready-to-use class for utterance-level classification (e.g, speaker-id,
    language-id, emotion recognition, keyword spotting, etc).

    The class assumes that an encoder called "embedding_model" and a model
    called "classifier" are defined in the yaml file. If you want to
    convert the predicted index into a corresponding text label, please
    provide the path of the label_encoder in a variable called 'lab_encoder_file'
    within the yaml.

    The class can be used either to run only the encoder (encode_batch()) to
    extract embeddings or to run a classification step (classify_batch()).

    Arguments
    ---------
    See ``Pretrained``

    Example
    -------
    >>> import torchaudio
    >>> from speechbrain.inference.classifiers import EncoderClassifier
    >>> # Model is downloaded from the speechbrain HuggingFace repo
    >>> tmpdir = getfixture("tmpdir")
    >>> classifier = EncoderClassifier.from_hparams(
    ...     source="speechbrain/spkrec-ecapa-voxceleb",
    ...     savedir=tmpdir,
    ... )
    >>> classifier.hparams.label_encoder.ignore_len()

    >>> # Compute embeddings
    >>> signal, fs = torchaudio.load("tests/samples/single-mic/example1.wav")
    >>> embeddings = classifier.encode_batch(signal)

    >>> # Classification
    >>> prediction = classifier.classify_batch(signal)
    )compute_featuresmean_var_normembedding_model
classifierNFc                 C   s   t |jdkr|d}|du rtj|jd | jd}|| j|| j}}| }| j	|}| j
||}| j||}|rR| j|tj|jd | jd}|S )a  Encodes the input audio into a single vector embedding.

        The waveforms should already be in the model's desired format.
        You can call:
        ``normalized = <this>.normalizer(signal, sample_rate)``
        to get a correctly converted signal in most cases.

        Arguments
        ---------
        wavs : torch.Tensor
            Batch of waveforms [batch, time, channels] or [batch, time]
            depending on the model. Make sure the sample rate is fs=16000 Hz.
        wav_lens : torch.Tensor
            Lengths of the waveforms relative to the longest one in the
            batch, tensor of shape [batch]. The longest one should have
            relative length 1.0 and others len(waveform) / max_length.
            Used for ignoring padding.
        normalize : bool
            If True, it normalizes the embeddings with the statistics
            contained in mean_var_norm_emb.

        Returns
        -------
        torch.Tensor
            The encoded batch
           r   N)device)lenshape	unsqueezetorchonesr   tofloatmodsr   r   r	   hparamsmean_var_norm_emb)selfwavswav_lens	normalizefeats
embeddings r   U/home/ubuntu/.local/lib/python3.10/site-packages/speechbrain/inference/classifiers.pyencode_batchF   s   
zEncoderClassifier.encode_batchc                 C   sJ   |  ||}| j|d}tj|dd\}}| jj|}||||fS )aa  Performs classification on the top of the encoded features.

        It returns the posterior probabilities, the index and, if the label
        encoder is specified it also the text label.

        Arguments
        ---------
        wavs : torch.Tensor
            Batch of waveforms [batch, time, channels] or [batch, time]
            depending on the model. Make sure the sample rate is fs=16000 Hz.
        wav_lens : torch.Tensor
            Lengths of the waveforms relative to the longest one in the
            batch, tensor of shape [batch]. The longest one should have
            relative length 1.0 and others len(waveform) / max_length.
            Used for ignoring padding.

        Returns
        -------
        out_prob
            The log posterior probabilities of each class ([batch, N_class])
        score:
            It is the value of the log-posterior for the best class ([batch,])
        index
            The indexes of the best class ([batch,])
        text_lab:
            List with the text labels corresponding to the indexes.
            (label encoder should be provided).
        r   dim)	r   r   r
   squeezer   maxr   label_encoderdecode_torch)r   r   r   embout_probscoreindextext_labr   r   r   classify_batchw   s
   z EncoderClassifier.classify_batchc                 K   sr   | j |fi |}|d}tdg}| ||}| j|d}tj|dd\}}	| j	j
|	}
|||	|
fS )a  Classifies the given audiofile into the given set of labels.

        Arguments
        ---------
        path : str
            Path to audio file to classify.
        **kwargs : dict
            Arguments forwarded to ``load_audio``.

        Returns
        -------
        out_prob : torch.Tensor
            The log posterior probabilities of each class ([batch, N_class])
        score : torch.Tensor
            It is the value of the log-posterior for the best class ([batch,])
        index : torch.Tensor
            The indexes of the best class ([batch,])
        text_lab : list of str
            List with the text labels corresponding to the indexes.
            (label encoder should be provided).
        r   g      ?r   r    r!   )
load_audior   r   tensorr   r   r
   r#   r$   r   r%   r&   )r   pathkwargswaveformbatch
rel_lengthr'   r(   r)   r*   r+   r   r   r   classify_file   s   
zEncoderClassifier.classify_filec                 C      |  ||S zRuns the classificationr,   r   r   r   r   r   r   forward      zEncoderClassifier.forward)NFN)	__name__
__module____qualname____doc__MODULES_NEEDEDr   r,   r4   r9   r   r   r   r   r      s    $

1# r   c                   @   s.   e Zd ZdZd	ddZd	ddZd	ddZdS )
AudioClassifierai  A ready-to-use class for utterance-level classification (e.g, speaker-id,
    language-id, emotion recognition, keyword spotting, etc).

    The class assumes that an encoder called "embedding_model" and a model
    called "classifier" are defined in the yaml file. If you want to
    convert the predicted index into a corresponding text label, please
    provide the path of the label_encoder in a variable called 'lab_encoder_file'
    within the yaml.

    The class can be used either to run only the encoder (encode_batch()) to
    extract embeddings or to run a classification step (classify_batch()).

    Arguments
    ---------
    See ``Pretrained``.

    Example
    -------
    >>> import torchaudio
    >>> from speechbrain.inference.classifiers import AudioClassifier
    >>> tmpdir = getfixture("tmpdir")
    >>> classifier = AudioClassifier.from_hparams(
    ...     source="speechbrain/cnn14-esc50",
    ...     savedir=tmpdir,
    ... )
    >>> signal = torch.randn(1, 16000)
    >>> prediction, _, _, text_lab = classifier.classify_batch(signal)
    >>> print(prediction.shape)
    torch.Size([1, 1, 50])
    Nc                 C   s   | | j}| j|}tjjj|| jj	d}| jj
r"| j|}nt|}| j|}|jdkr7|d}| j|}tj|dd\}}	| jj|	}
|||	|
fS )a  Performs classification on the top of the encoded features.

        It returns the posterior probabilities, the index and, if the label
        encoder is specified it also the text label.

        Arguments
        ---------
        wavs : torch.Tensor
            Batch of waveforms [batch, time, channels] or [batch, time]
            depending on the model. Make sure the sample rate is fs=16000 Hz.
        wav_lens : torch.Tensor
            Lengths of the waveforms relative to the longest one in the
            batch, tensor of shape [batch]. The longest one should have
            relative length 1.0 and others len(waveform) / max_length.
            Used for ignoring padding.

        Returns
        -------
        out_prob : torch.Tensor
            The log posterior probabilities of each class ([batch, N_class])
        score : torch.Tensor
            It is the value of the log-posterior for the best class ([batch,])
        index : torch.Tensor
            The indexes of the best class ([batch,])
        text_lab : list of str
            List with the text labels corresponding to the indexes.
            (label encoder should be provided).
        )power   )r    r    r!   )r   r   r   compute_stftspeechbrain
processingfeaturesspectral_magnituder   spec_mag_poweruse_melspectracompute_fbankr   log1pr	   ndimmeanr
   r$   r%   r&   )r   r   r   X_stftX_stft_power	net_inputr   	out_probsr)   r*   r+   r   r   r   r,      s   


zAudioClassifier.classify_batchc                 C   s   t |\}}t|||tjd}t|\}}|| j}| jj	}||krCt
d|| tjj||d| j}|jddd}||}| |\}	}
}}|	|
||fS )a  Classifies the given audiofile into the given set of labels.

        Arguments
        ---------
        path : str
            Path to audio file to classify.
        savedir : str
            Path to folder for caching downloads.

        Returns
        -------
        out_prob
            The log posterior probabilities of each class ([batch, N_class])
        score:
            It is the value of the log-posterior for the best class ([batch,])
        index
            The indexes of the best class ([batch,])
        text_lab:
            List with the text labels corresponding to the indexes.
            (label encoder should be provided).
        )sourcesavedirlocal_strategyz(Resampling the audio from {} Hz to {} Hz)	orig_freqnew_freqr   T)r"   keepdim)r   r   r   SYMLINK
torchaudioloadr   r   r   sample_rateprintformat
transformsResamplerO   r,   )r   r/   rU   rT   flr2   fs_filefs_modeltfrS   r)   r*   r+   r   r   r   r4     s2   zAudioClassifier.classify_filec                 C   r5   r6   r7   r8   r   r   r   r9   C  r:   zAudioClassifier.forwardr;   )r<   r=   r>   r?   r,   r4   r9   r   r   r   r   rA      s
    

22rA   )r?   r   r[   rF    speechbrain.inference.interfacesr   speechbrain.utils.data_utilsr   speechbrain.utils.fetchingr   r   r   rA   r   r   r   r   <module>   s     &