o
    si                     @   sP   d dl Z d dlmZ d dlmZ d dlmZmZ d dlm	Z	 G dd deZ
dS )    N)_Loss)STFTFBEncoder)magc                       s@   e Zd ZdZd fdd	Zdd Zdd	d
Zedd Z  Z	S )SingleSrcMultiScaleSpectrala  Measure multi-scale spectral loss as described in [1]

    Args:
        n_filters (list): list containing the number of filter desired for
            each STFT
        windows_size (list): list containing the size of the window desired for
            each STFT
        hops_size (list): list containing the size of the hop desired for
            each STFT

    Shape:
        - est_targets : :math:`(batch, time)`.
        - targets: :math:`(batch, time)`.

    Returns:
        :class:`torch.Tensor`: with shape [batch]

    Examples
        >>> import torch
        >>> targets = torch.randn(10, 32000)
        >>> est_targets = torch.randn(10, 32000)
        >>> # Using it by itself on a pair of source/estimate
        >>> loss_func = SingleSrcMultiScaleSpectral()
        >>> loss = loss_func(est_targets, targets)

        >>> import torch
        >>> from asteroid.losses import PITLossWrapper
        >>> targets = torch.randn(10, 2, 32000)
        >>> est_targets = torch.randn(10, 2, 32000)
        >>> # Using it with PITLossWrapper with sets of source/estimates
        >>> loss_func = PITLossWrapper(SingleSrcMultiScaleSpectral(),
        >>>                            pit_from='pw_pt')
        >>> loss = loss_func(est_targets, targets)

    References
        [1] Jesse Engel and Lamtharn (Hanoi) Hantrakul and Chenjie Gu and
        Adam Roberts "DDSP: Differentiable Digital Signal Processing" ICLR 2020.
    N      ?c                    s~   t    d u rg dd u rg d d u rg d | _| _ | _|| _t fddtt	| jD | _
d S )N)i               @       )r   r	   r
   r   r   r      c                 3   s,    | ]}t t| |  | V  qd S )N)r   r   ).0i	hops_size	n_filterswindows_size X/home/ubuntu/.local/lib/python3.10/site-packages/asteroid/losses/multi_scale_spectral.py	<genexpr>?   s
    
z7SingleSrcMultiScaleSpectral.__init__.<locals>.<genexpr>)super__init__r   r   r   alphann
ModuleListrangelenencoders)selfr   r   r   r   	__class__r   r   r   0   s   
z$SingleSrcMultiScaleSpectral.__init__c                 C   sP   |j d }|d}|d}tj||jd}| jD ]}|| |||7 }q|S )Nr      )device)shape	unsqueezetorchzerosr$   r   compute_spectral_loss)r    
est_targettarget
batch_sizelossencoderr   r   r   forwardD   s   



z#SingleSrcMultiScaleSpectral.forward:0yE>c           
      C   sp   |j d }t|||d}t|||d}| || }| t|| t||  }	|| j|	  S )Nr   )r%   r   viewnorm1r'   logr   )
r    r.   r*   r+   EPSr,   spect_est_targetspect_targetlinear_losslog_lossr   r   r   r)   N   s   
"z1SingleSrcMultiScaleSpectral.compute_spectral_lossc                 C   s   t j| dddS )Nr#   )pdim)r'   norm)ar   r   r   r3   V   s   z!SingleSrcMultiScaleSpectral.norm1)NNNr   )r0   )
__name__
__module____qualname____doc__r   r/   r)   staticmethodr3   __classcell__r   r   r!   r   r      s    '

r   )r'   torch.nnr   torch.nn.modules.lossr   asteroid_filterbanksr   r   asteroid_filterbanks.transformsr   r   r   r   r   r   <module>   s    