o
    %ݫi                     @   sF   d Z ddlZddlm  mZ ddlmZ dd Zdd Zdd	 Z	dS )
z:Non-negative matrix factorization

Authors
 * Cem Subakan
    N)spectral_magnitudec                 C   s@   t | dddddddf | dddddddf }|S )ab  Returns the phase of a complex spectrogram.

    Arguments
    ---------
    stft : torch.Tensor
        A tensor, output from the stft function.

    Returns
    -------
    phase : torch.Tensor

    Example
    -------
    >>> BS, nfft, T = 10, 20, 300
    >>> X_stft = torch.randn(BS, nfft//2 + 1, T, 2)
    >>> phase_mix = spectral_phase(X_stft)
    N   r   )torchatan2)stftphase r   N/home/ubuntu/.local/lib/python3.10/site-packages/speechbrain/processing/NMF.pyspectral_phase   s   <r
   c                 C   s  | \}}|j d }|dddd|d }|j d }d}|jdd| }|| }tj||gdd}	|	d}
|d}dt|
| }|tj|dd|  }t	dD ]!}|t
|	||  }|t
|	 | }|tj|dd|  }qV||9 }t
|	d	d	d	|f |d	|d	d	f }tj|d|d| dd}tj|dd}t
|	d	d	|d	f ||d	d	d	f }tj|d|d| dd}tj|dd}||fS )
a  This function separates the mixture signals, given NMF template matrices.

    Arguments
    ---------
    Whats : list
        This list contains the list [W1, W2], where W1 W2 are respectively
        the NMF template matrices that correspond to source1 and source2.
        W1, W2 are of size [nfft/2 + 1, K], where nfft is the fft size for STFT,
        and K is the number of vectors (templates) in W.
    Xmix : torch.Tensor
        This is the magnitude spectra for the mixtures.
        The size is [BS x T x nfft//2 + 1] where,
        BS = batch size, nfft = fft size, T = number of time steps in the spectra.

    Returns
    -------
    X1hat : Separated spectrum for source1
        Size = [BS x (nfft/2 +1) x T] where,
        BS = batch size, nfft = fft size, T = number of time steps in the spectra.
    X2hat : Separated Spectrum for source2
        The size definitions are the same as above.

    Example
    -------
    >>> BS, nfft, T = 4, 20, 400
    >>> K1, K2 = 10, 10
    >>> W1hat = torch.randn(nfft//2 + 1, K1)
    >>> W2hat = torch.randn(nfft//2 + 1, K2)
    >>> Whats = [W1hat, W2hat]
    >>> Xmix = torch.randn(BS, T, nfft//2 + 1)
    >>> X1hat, X2hat = NMF_separate_spectra(Whats, Xmix)
    r      r   g#B;dimg?i  N)shapepermutereshapesizetsumr   catrandrangematmulsplit	unsqueeze)WhatsXmixW1W2	nmixturesnepsgzwKK1hepvnhXhat1Xhat2r   r   r	   NMF_separate_spectra$   s0   !
 


, , r-   c              	   C   s  t j|||d}t|}t|dd}g g }	}
d}t| jd D ]}| | || |  ||   d|| d tjt	|| dt
|| dgdd }|| || |  ||   d|| d tjt	|| dt
|| dgdd }|ddddd	}|ddddd	}||}||}d
}|||   }|||   }|	| |
| q |	|
fS )a  This function reconstructs the separated spectra into waveforms.

    Arguments
    ---------
    X1hat : torch.Tensor
        The separated spectrum for source 1 of size [BS, nfft/2 + 1, T],
        where,  BS = batch size, nfft = fft size, T = length of the spectra.
    X2hat : torch.Tensor
        The separated spectrum for source 2 of size [BS, nfft/2 + 1, T].
        The size definitions are the same as Xhat1.
    X_stft : torch.Tensor
        This is the magnitude spectra for the mixtures.
        The size is [BS x nfft//2 + 1 x T x 2] where,
        BS = batch size, nfft = fft size, T = number of time steps in the spectra.
        The last dimension is to represent complex numbers.
    sample_rate : int
        The sampling rate (in Hz) in which we would like to save the results.
    win_length : int
        The length of stft windows (in ms).
    hop_length : int
        The length with which we shift the STFT windows (in ms).

    Returns
    -------
    x1hats : list
        List of waveforms for source 1.
    x2hats : list
        List of waveforms for source 2.

    Example
    -------
    >>> BS, nfft, T = 10, 512, 16000
    >>> sample_rate, win_length, hop_length = 16000, 25, 10
    >>> X1hat = torch.randn(BS, nfft//2 + 1, T)
    >>> X2hat = torch.randn(BS, nfft//2 + 1, T)
    >>> X_stft = torch.randn(BS, nfft//2 + 1, T, 2)
    >>> x1hats, x2hats = reconstruct_results(X1hat, X2hat, X_stft, sample_rate, win_length, hop_length)
    )sample_rate
win_length
hop_lengthr   )powerg}:r   r   r   r      
   )spfISTFTr
   r   r   r   r   r   r   cossinr   stdappend)X1hatX2hatX_stftr.   r/   r0   r5   	phase_mixmag_mixx1hatsx2hatsr!   i
X1hat_stft
X2hat_stftshat1shat2
div_factorx1x2r   r   r	   reconstruct_resultsj   sP   .
  
rI   )
__doc__r   speechbrain.processing.features
processingfeaturesr4   r   r
   r-   rI   r   r   r   r	   <module>   s    F