o
    i                     @   s  d dl mZmZ d dlZd dlm  mZ d dlmZ	 d dl
mZ d dlmZ d dlmZmZmZ eejedkZ	 	 d'deejef ded	ed
eejef fddZd(d
ejfddZdeejef dejd
eeejef eejef f fddZ	d)deejef deejef ded
eejef fddZdeejef deejef d
eejef fddZ				d*deejef d ejd!ed"ededed
eejef fd#d$Z	d+deejef d
eejef fd%d&ZdS ),    )TupleUnionN)parse)ComplexTensor)einsummatmulreversez1.9.0signalframe_length
frame_stepreturnc                    s   t | trt| j ||}t| j ||}t||S tr7t| r7t| j ||}t| j ||}t||S t	
| d d fd|} t fddtd| d  d |D g }| d|f jg |  dd d R  } | S )	zExpands signal into frames of frame_length.

    Args:
        signal : (B * F, D, T)
    Returns:
        torch.Tensor: (B * F, D, T, W)
    r      constantc                    s   g | ]}t t||  qS  )listrange.0ir
   r   J/home/ubuntu/.local/lib/python3.10/site-packages/espnet2/enh/layers/wpe.py
<listcomp>*   s    z"signal_framing.<locals>.<listcomp>.N)
isinstancer   signal_framingrealimagis_torch_1_9_plustorch
is_complexcomplexFpadsumr   sizeview)r	   r
   r   	pad_valuer   r   indicesr   r   r   r      s"   


,r   c                 C   s$   | j d | jd  }|j|d}|S )zCalculates power for `signal`

    Args:
        signal : Single frequency signal
            with shape (F, C, T).
        axis: reduce_mean axis
    Returns:
        Power with shape (F, T)

       dim)r   r   mean)r	   r+   powerr   r   r   	get_power5   s   r.   Yinverse_powerc                 C   s   |  dksJ |  |d| dks"J |d| df|  \}}}t| |dddd|| | d ddf }t|dd}| |dd|| d ddf  }td	||}	|	||| || }	td
|| d|| d df }
|	|
fS )a  Calculates weighted correlations of a window of length taps

    Args:
        Y : Complex-valued STFT signal with shape (F, C, T)
        inverse_power : Weighting factor with shape (F, T)
        taps (int): Lenghts of correlation window
        delay (int): Delay for the weighting factor

    Returns:
        Correlation matrix of shape (F, taps*C, taps*C)
        Correlation vector of shape (F, taps, C, C)
    r)   r   r   )r
   r   .Nr   r*   zfdtk,fetl->fkdlezfdtk,fet->fked)r+   r$   r   r   conjr   reshape)r/   r0   tapsdelayr!   CTPsiPsi_conj_normcorrelation_matrixcorrelation_vectorr   r   r   get_correlationsE   s   ,$r;   绽|=r9   r:   epsc                 C   s   |  \}}}}|dddd |||| }tj|  d| j| jd}tdd t	| 
 d D | jd	d
  }|j| }| || 7 } |  }	t||	dd	}
|
||||dddd}|S )aD  Calculate (conjugate) filter matrix based on correlations for one freq.

    Args:
        correlation_matrix : Correlation matrix (F, taps * C, taps * C)
        correlation_vector : Correlation vector (F, taps, C, C)
        eps:

    Returns:
        filter_matrix_conj (torch.complex/ComplexTensor): (F, taps, C, C)
    r   r)   r      r   )dtypedevicec                 s   s    | ]}d V  qdS )r   Nr   )r   _r   r   r   	<genexpr>   s    z)get_filter_matrix_conj.<locals>.<genexpr>r(   N)r$   permute
contiguousr%   r   eyer?   r@   tupler   r+   shapeinverser   	transpose)r9   r:   r=   r!   r3   r5   rA   rE   rG   inv_correlation_matrixstacked_filter_conjfilter_matrix_conjr   r   r   get_filter_matrix_conjn   s(    
rM   rL   c                    s   t trt}tjntrtrt}tjntd	d |j
 fddt|D dd}|d||f}| S )zperform_filter_operation

    Args:
        Y : Complex-valued STFT signal of shape (F, C, T)
        filter Matrix (F, taps, C, C)
    z?Please update your PyTorch version to 1.9+ for complex support.r   c              	      sB   g | ]}d d d d d   | f | dfdddqS )Nr   r   )modevaluer   r   r6   r/   r4   pad_funcr   r   r      s    4z,perform_filter_operation.<locals>.<listcomp>r   r*   zfpde,pfdt->fet)r   r   FCr"   r   r   r   r!   
ValueErrorr$   stackr   r   )r/   rL   r3   r4   complex_moduleY_tildereverb_tailr   rP   r   perform_filter_operation   s$   

rX   
   r>   Tr-   r3   r4   c                 C   s   |   dd |  dd ksJ |   dd }| jdg|   dd R  } |d|  d }|r?dtj||d }n|}t| |||\}}t||}	t| |	||}
|
jg ||   dd R  }
|
S )aB  WPE for one iteration

    Args:
        Y: Complex valued STFT signal with shape (..., C, T)
        power: : (..., T)
        taps: Number of filter taps
        delay: Delay as a guard interval, such that X does not become zero.
        eps:
        inverse_power (bool):
    Returns:
        enhanced: (..., C, T)
    Nr(   r   r   )min)r$   r%   r   clampr;   rM   rX   )r/   r-   r3   r4   r=   r0   batch_freq_sizer9   r:   rL   enhancedr   r   r   wpe_one_iteration   s   $
 r^   c                 C   s.   | }t |D ]}t|}t| |||d}q|S )zWPE

    Args:
        Y: Complex valued STFT signal with shape (F, C, T)
        taps: Number of filter taps
        delay: Delay as a guard interval, such that X does not become zero.
        iterations:

    Returns:
        enhanced: (F, C, T)

    )r3   r4   )r   r.   r^   )r/   r3   r4   
iterationsr]   rA   r-   r   r   r   wpe   s
   r`   )r   )r(   )r<   )rY   r>   r<   T)rY   r>   r>   ) typingr   r   r   torch.nn.functionalnn
functionalr!   torch_complex.functionalrR   packaging.versionr   Vtorch_complex.tensorr    espnet2.enh.layers.complex_utilsr   r   r   __version__r   Tensorintr   r.   r;   floatrM   rX   boolr^   r`   r   r   r   r   <module>   s    
#
,
-
'
)