a
    d2                     @   s   d dl mZmZmZmZ d dlmZmZ d dlm	Z	m
Z
 d dlmZ d dlmZmZmZmZ d dlmZmZ eeeegsddgZn
esdgZG d	d deZd
S )    )AnyOptionalSequenceUnion)Tensortensor)_srmr_arg_validate,speech_reverberation_modulation_energy_ratio)Metric)_GAMMATONE_AVAILABEL_MATPLOTLIB_AVAILABLE_TORCHAUDIO_AVAILABEL_TORCHAUDIO_GREATER_EQUAL_0_10)_AX_TYPE_PLOT_OUT_TYPE(SpeechReverberationModulationEnergyRatio-SpeechReverberationModulationEnergyRatio.plotc                       s   e Zd ZU dZeed< eed< dZeed< dZeed< dZ	eed< d	Z
ee ed
< d	Zee ed< deeeeee eeed	d	 fddZed	dddZedddZdeeee d	f ee edddZ  ZS )r   aL	  Calculate `Speech-to-Reverberation Modulation Energy Ratio`_ (SRMR).

    SRMR is a non-intrusive metric for speech quality and intelligibility based on
    a modulation spectral representation of the speech signal.
    This code is translated from `SRMRToolbox`_ and `SRMRpy`_.

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): float tensor with shape ``(...,time)``

    As output of `forward` and `compute` the metric returns the following output

    - ``srmr`` (:class:`~torch.Tensor`): float scaler tensor

    .. note:: using this metrics requires you to have ``gammatone`` and ``torchaudio`` installed.
        Either install as ``pip install torchmetrics[audio]`` or ``pip install torchaudio``
        and ``pip install git+https://github.com/detly/gammatone``.

    .. note::
        This implementation is experimental, and might not be consistent with the matlab
        implementation `SRMRToolbox`_, especially the fast implementation.
        The slow versions, a) fast=False, norm=False, max_cf=128, b) fast=False, norm=True, max_cf=30, have
        a relatively small inconsistence.

    Args:
        fs: the sampling rate
        n_cochlear_filters: Number of filters in the acoustic filterbank
        low_freq: determines the frequency cutoff for the corresponding gammatone filterbank.
        min_cf: Center frequency in Hz of the first modulation filter.
        max_cf: Center frequency in Hz of the last modulation filter. If None is given,
            then 30 Hz will be used for `norm==False`, otherwise 128 Hz will be used.
        norm: Use modulation spectrum energy normalization
        fast: Use the faster version based on the gammatonegram.
            Note: this argument is inherited from `SRMRpy`_. As the translated code is based to pytorch,
            setting `fast=True` may slow down the speed for calculating this metric on GPU.

    Raises:
        ModuleNotFoundError:
            If ``gammatone`` or ``torchaudio`` package is not installed

    Example:
        >>> import torch
        >>> from torchmetrics.audio import SpeechReverberationModulationEnergyRatio
        >>> g = torch.manual_seed(1)
        >>> preds = torch.randn(8000)
        >>> srmr = SpeechReverberationModulationEnergyRatio(8000)
        >>> srmr(preds)
        tensor(0.3354)

    msumtotalFfull_state_updateTis_differentiablehigher_is_betterNplot_lower_boundplot_upper_bound   }      )	fsn_cochlear_filterslow_freqmin_cfmax_cfnormfastkwargsreturnc           	   	      s   t  jf i | trtrts&tdt|||||||d || _|| _|| _	|| _
|| _|| _|| _| jdtddd | jdtddd d S )	Na  speech_reverberation_modulation_energy_ratio requires you to have `gammatone` and `torchaudio>=0.10` installed. Either install as ``pip install torchmetrics[audio]`` or ``pip install torchaudio>=0.10`` and ``pip install git+https://github.com/detly/gammatone``)r   r   r   r    r!   r"   r#   r   g        sum)defaultZdist_reduce_fxr   r   )super__init__r   r   r   ModuleNotFoundErrorr   r   r   r   r    r!   r"   r#   Z	add_stater   )	selfr   r   r   r    r!   r"   r#   r$   	__class__ `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/audio/srmr.pyr)   a   s.    
z1SpeechReverberationModulationEnergyRatio.__init__)predsr%   c              	   C   sV   t || j| j| j| j| j| j| j| j	j
}|  j	| 7  _	|  j| 7  _dS )zUpdate state with predictions.N)r	   r   r   r   r    r!   r"   r#   tor   Zdevicer&   r   Znumel)r+   r0   Zmetric_val_batchr.   r.   r/   update   s    z/SpeechReverberationModulationEnergyRatio.update)r%   c                 C   s   | j | j S )zCompute metric.)r   r   )r+   r.   r.   r/   compute   s    z0SpeechReverberationModulationEnergyRatio.compute)valaxr%   c                 C   s   |  ||S )aN  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> import torch
            >>> from torchmetrics.audio import SpeechReverberationModulationEnergyRatio
            >>> metric = SpeechReverberationModulationEnergyRatio(8000)
            >>> metric.update(torch.rand(8000))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.audio import SpeechReverberationModulationEnergyRatio
            >>> metric = SpeechReverberationModulationEnergyRatio(8000)
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(torch.rand(8000)))
            >>> fig_, ax_ = metric.plot(values)

        )Z_plot)r+   r4   r5   r.   r.   r/   plot   s    &r   )r   r   r   NFF)NN)__name__
__module____qualname____doc__r   __annotations__r   boolr   r   r   r   floatr   intr   r)   r2   r3   r   r   r   r   r6   __classcell__r.   r.   r,   r/   r   %   s8   
3      '	N)typingr   r   r   r   Ztorchr   r   Z"torchmetrics.functional.audio.srmrr   r	   Ztorchmetrics.metricr
   Ztorchmetrics.utilities.importsr   r   r   r   Ztorchmetrics.utilities.plotr   r   allZ__doctest_skip__r   r.   r.   r.   r/   <module>   s   
