o
    .wi                     @   s   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
 d dlmZ d dlmZmZmZ d dlmZmZ dd	d
giZesAdgZG dd deZdS )    )Sequence)AnyOptionalUnion)Tensortensor)'non_intrusive_speech_quality_assessment)Metric)_LIBROSA_AVAILABLE_MATPLOTLIB_AVAILABLE_REQUESTS_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPE#NonIntrusiveSpeechQualityAssessmentlibrosarequests(NonIntrusiveSpeechQualityAssessment.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d
< dZeed< dededdf fddZdeddfddZdefddZddeeee df dee defddZ  ZS )r   uJ  `Non-Intrusive Speech Quality Assessment`_ (NISQA v2.0) [1], [2].

    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

    - ``nisqa`` (:class:`~torch.Tensor`): float tensor reduced across the batch with shape ``(5,)`` corresponding to
      overall MOS, noisiness, discontinuity, coloration and loudness in that order

    .. hint::
        Using this metric requires you to have ``librosa`` and ``requests`` installed. Install as
        ``pip install librosa requests``.

    .. caution::
        The ``forward`` and ``compute`` methods in this class return values reduced across the batch. To obtain
        values for each sample, you may use the functional counterpart
        :func:`~torchmetrics.functional.audio.nisqa.non_intrusive_speech_quality_assessment`.

    Args:
        fs: sampling frequency of input

    Raises:
        ModuleNotFoundError:
            If ``librosa`` or ``requests`` are not installed

    Example:
        >>> import torch
        >>> from torchmetrics.audio import NonIntrusiveSpeechQualityAssessment
        >>> _ = torch.manual_seed(42)
        >>> preds = torch.randn(16000)
        >>> nisqa = NonIntrusiveSpeechQualityAssessment(16000)
        >>> nisqa(preds)
        tensor([1.0433, 1.9545, 2.6087, 1.3460, 1.7117])

    References:
        - [1] G. Mittag and S. Möller, "Non-intrusive speech quality assessment for super-wideband speech communication
          networks", in Proc. ICASSP, 2019.
        - [2] G. Mittag, B. Naderi, A. Chehadi and S. Möller, "NISQA: A deep CNN-self-attention model for
          multidimensional speech quality prediction with crowdsourced datasets", in Proc. INTERSPEECH, 2021.

    	sum_nisqatotalFfull_state_updateis_differentiableThigher_is_better        plot_lower_boundg      @plot_upper_boundfskwargsreturnNc                    sx   t  jd	i | trtstdt|tr|dkr!td| || _| j	dt
g ddd | j	dt
ddd d S )
NziNISQA metric requires that librosa and requests are installed. Install as `pip install librosa requests`.r   z9Argument `fs` expected to be a positive integer, but got r   )r   r   r   r   r   sum)defaultdist_reduce_fxr    )super__init__r
   r   ModuleNotFoundError
isinstanceint
ValueErrorr   	add_stater   )selfr   r   	__class__r!   U/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/audio/nisqa.pyr#   X   s   z,NonIntrusiveSpeechQualityAssessment.__init__predsc                 C   sP   t || j| jj}|dd}|  j|jdd7  _|  j|jd 7  _dS )zUpdate state with predictions.   r   )dimN)	r   r   tor   devicereshaper   r   shape)r)   r-   nisqa_batchr!   r!   r,   updatef   s   
z*NonIntrusiveSpeechQualityAssessment.updatec                 C   s   | j | j S )zCompute metric.)r   r   )r)   r!   r!   r,   computeq   s   z+NonIntrusiveSpeechQualityAssessment.computevalaxc                 C   s   |  ||S )aF  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: A 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 NonIntrusiveSpeechQualityAssessment
            >>> metric = NonIntrusiveSpeechQualityAssessment(16000)
            >>> metric.update(torch.randn(16000))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

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

        )_plot)r)   r8   r9   r!   r!   r,   plotu   s   &r   )NN)__name__
__module____qualname____doc__r   __annotations__r   boolr   r   r   floatr   r&   r   r#   r6   r7   r   r   r   r   r   r;   __classcell__r!   r!   r*   r,   r   #   s   
 ,2N)collections.abcr   typingr   r   r   torchr   r   #torchmetrics.functional.audio.nisqar   torchmetrics.metricr	   torchmetrics.utilities.importsr
   r   r   torchmetrics.utilities.plotr   r   __doctest_requires____doctest_skip__r   r!   r!   r!   r,   <module>   s   