
    i                         d dl mZ d dl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 d dlmZmZ  eeeg      sdd	gZnesd	gZ G d
 de      Zy)    )Sequence)AnyOptionalUnion)Tensortensor)_srmr_arg_validate,speech_reverberation_modulation_energy_ratio)Metric)_GAMMATONE_AVAILABLE_MATPLOTLIB_AVAILABLE_TORCHAUDIO_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPE(SpeechReverberationModulationEnergyRatioz-SpeechReverberationModulationEnergyRatio.plotc                       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dededededee   dedededd	f fdZdedd	fdZdefdZddeeee   d	f   dee   defdZ xZS )r   a;	  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

    .. hint::
        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``.

    .. attention::
        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 inconsistency.

    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:
        >>> from torch import randn
        >>> from torchmetrics.audio import SpeechReverberationModulationEnergyRatio
        >>> preds = randn(8000)
        >>> srmr = SpeechReverberationModulationEnergyRatio(8000)
        >>> srmr(preds)
        tensor(0.3191)

    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           	      L   t        	|   d	i | t        rt        st	        d      t        |||||||       || _        || _        || _        || _	        || _
        || _        || _        | j                  dt        d      d       | j                  dt        d      d       y )
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)defaultdist_reduce_fxr   r    )super__init__r   r   ModuleNotFoundErrorr	   r   r   r   r   r   r   r    	add_stater   )
selfr   r   r   r   r   r   r    r!   	__class__s
            l/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/audio/srmr.pyr)   z1SpeechReverberationModulationEnergyRatio.__init__a   s     	"6"$,@%n 
 	1	
 "4 		vvc{5Iwq	%H    predsc           
         t        || j                  | j                  | j                  | j                  | j
                  | j                  | j                        j                  | j                  j                        }| xj                  |j                         z  c_	        | xj                  |j                         z  c_        y)zUpdate state with predictions.N)r
   r   r   r   r   r   r   r    tor   devicer$   r   numel)r,   r0   metric_val_batchs      r.   updatez/SpeechReverberationModulationEnergyRatio.update   s    G477D33T]]DKKQUQ\Q\^b^g^gimirir

"TYY
 	 			%))++	

&,,..
r/   c                 4    | j                   | j                  z  S )zCompute metric.)r   r   )r,   s    r.   computez0SpeechReverberationModulationEnergyRatio.compute   s    yy4::%%r/   valaxc                 &    | j                  ||      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)

        )_plot)r,   r9   r:   s      r.   plotz-SpeechReverberationModulationEnergyRatio.plot   s    L zz#r""r/   )   }      NFF)NN)__name__
__module____qualname____doc__r   __annotations__r   boolr   r   r   r   floatr   intr   r)   r6   r8   r   r   r   r   r=   __classcell__)r-   s   @r.   r   r   %   s%   1f LM#t#"t"!d!(,huo,(,huo,
 #%"&%I%I  %I 	%I
 %I %I %I %I %I 
%IN/F /t /& &&#fhv&6<= &#(S[J\ &#hv &#r/   N)collections.abcr   typingr   r   r   torchr   r   "torchmetrics.functional.audio.srmrr	   r
   torchmetrics.metricr   torchmetrics.utilities.importsr   r   r   torchmetrics.utilities.plotr   r   all__doctest_skip__r   r'   r/   r.   <module>rS      sb    % ' '   ' 
 A
 "789BDst	GHV#v V#r/   