o
    ¡¿¯i:(  ã                   @   s²   d dl Z d dlmZ d dlmZmZmZ d dlmZ G dd„ dej	ƒZ
G dd„ dej	ƒZG dd	„ d	ej	ƒZed
krWeddddddddddd
Ze  ddd¡Zeeeƒjƒ dS dS )é    N)Ú	SingleRNNÚmerge_featureÚsplit_feature)Úchoose_normc                       s@   e Zd ZdZ				d‡ fdd„	Zdefd	d
„Zdd„ Z‡  ZS )ÚMemLSTMa5  the Mem-LSTM of SkiM

    args:
        hidden_size: int, dimension of the hidden state.
        dropout: float, dropout ratio. Default is 0.
        bidirectional: bool, whether the LSTM layers are bidirectional.
            Default is False.
        mem_type: 'hc', 'h', 'c' or 'id'.
            It controls whether the hidden (or cell) state of
            SegLSTM will be processed by MemLSTM.
            In 'id' mode, both the hidden and cell states will
            be identically returned.
        norm_type: gLN, cLN. cLN is for causal implementation.
    ç        FÚhcÚcLNc                    s°   t ƒ  ¡  || _|| _t|ƒd | | _|| _|dv s"J d|› ƒ‚|dv r;td| j| j||d| _t	|| jdd| _
|d	v rVtd| j| j||d| _t	|| jdd| _d S d S )
Né   )r   ÚhÚcÚidz4only support 'hc', 'h', 'c' and 'id', current type: )r   r   ÚLSTM)Ú
input_sizeÚhidden_sizeÚdropoutÚbidirectionalÚBTD©Ú	norm_typeÚchannel_sizeÚshape)r   r   )ÚsuperÚ__init__r   r   Úintr   Úmem_typer   Úh_netr   Úh_normÚc_netÚc_norm)Úselfr   r   r   r   r   ©Ú	__class__© úK/home/ubuntu/.local/lib/python3.10/site-packages/espnet2/enh/layers/skim.pyr      s>   

ûûÿûÿøzMemLSTM.__init__Úreturnc                 C   s   d| j › d| j› S )Nz
Mem_type: z, bidirectional: )r   r   )r    r#   r#   r$   Ú
extra_reprI   s   zMemLSTM.extra_reprc                 C   s–  | j dkr|}n‘|\}}|j\}}}|| }	| dd¡ ¡  |	||| ¡}| dd¡ ¡  |	||| ¡}| j dkrN||  |  |¡¡ }||  |  |¡¡ }n)| j dkrc||  |  |¡¡ }t	 
|¡}n| j dkrwt	 
|¡}||  |  |¡¡ }| |	| ||¡ dd¡ ¡ }| |	| ||¡ dd¡ ¡ }||f}| jsÉg }
|D ]$}t	 
|¡}|d d …d d…d d …f |d d …dd …d d …f< |
 |¡ q t|
ƒ}|S )Nr   r
   r   r   r   r   éÿÿÿÿ)r   r   Ú	transposeÚ
contiguousÚviewr   r   r   r   ÚtorchÚ
zeros_liker   ÚappendÚtuple)r    r   ÚSÚret_valr   r   ÚdÚBSÚHÚBÚcausal_ret_valÚxÚx_r#   r#   r$   ÚforwardL   s6   





0zMemLSTM.forward)r   Fr   r	   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ústrr&   r8   Ú__classcell__r#   r#   r!   r$   r      s    ú,r   c                       s,   e Zd ZdZ	d	‡ fdd„	Zdd„ Z‡  ZS )
ÚSegLSTMa¶  the Seg-LSTM of SkiM

    args:
        input_size: int, dimension of the input feature.
            The input should have shape (batch, seq_len, input_size).
        hidden_size: int, dimension of the hidden state.
        dropout: float, dropout ratio. Default is 0.
        bidirectional: bool, whether the LSTM layers are bidirectional.
            Default is False.
        norm_type: gLN, cLN. cLN is for causal implementation.
    r   Fr	   c                    sp   t ƒ  ¡  || _|| _t|ƒd | _tj||dd|d| _tj	|d| _
t || j |¡| _t||dd| _d S )Nr
   T)Úbatch_firstr   )Úpr   r   )r   r   r   r   r   Únum_directionÚnnr   ÚlstmÚDropoutr   ÚLinearÚprojr   Únorm)r    r   r   r   r   r   r!   r#   r$   r      s    
ûÿzSegLSTM.__init__c           
      C   s´   |j \}}}|d u r&| j}t ||| j¡ |j¡}t ||| j¡ |j¡}n|\}}|  |||f¡\}	\}}|  |	¡}	|  	|	 
¡  d|	j d ¡¡ |j ¡}	||  |	¡ }	|	||ffS )Nr'   é   )r   rB   r+   Úzerosr   ÚtoÚdevicerD   r   rG   r)   r*   rH   )
r    Úinputr   r4   ÚTr3   r1   r   r   Úoutputr#   r#   r$   r8   —   s   
ÿzSegLSTM.forward)r   Fr	   )r9   r:   r;   r<   r   r8   r>   r#   r#   r!   r$   r?   s   s
    ÿr?   c                       s@   e Zd ZdZ							d‡ fd	d
„	Zdd„ Zdd„ Z‡  ZS )ÚSkiMaþ  Skipping Memory Net

    args:
        input_size: int, dimension of the input feature.
            Input shape shoud be (batch, length, input_size)
        hidden_size: int, dimension of the hidden state.
        output_size: int, dimension of the output size.
        dropout: float, dropout ratio. Default is 0.
        num_blocks: number of basic SkiM blocks
        segment_size: segmentation size for splitting long features
        bidirectional: bool, whether the RNN layers are bidirectional.
        mem_type: 'hc', 'h', 'c', 'id' or None.
            It controls whether the hidden (or cell) state of SegLSTM
            will be processed by MemLSTM.
            In 'id' mode, both the hidden and cell states will
            be identically returned.
            When mem_type is None, the MemLSTM will be removed.
        norm_type: gLN, cLN. cLN is for causal implementation.
        seg_overlap: Bool, whether the segmentation will reserve 50%
            overlap for adjacent segments.Default is False.
    r   rI   é   Tr   ÚgLNFc              
      sì   t ƒ  ¡  || _|| _|| _|| _|| _|| _|| _|	| _	|
| _
|dv s+J d|› ƒ‚t g ¡| _t|ƒD ]}| j t|||||	d¡ q5| jd urft g ¡| _t|d ƒD ]}| j t|||||	d¡ qVt t ¡ t ||d¡¡| _d S )N)r   r   r   r   Nz;only support 'hc', 'h', 'c', 'id', and None, current type: )r   r   r   r   r   r
   )r   r   r   r   )r   r   r   Úoutput_sizer   Úsegment_sizer   Ú
num_blocksr   r   Úseg_overlaprC   Ú
ModuleListÚ	seg_lstmsÚranger-   r?   Ú	mem_lstmsr   Ú
SequentialÚPReLUÚConv1dÚ	output_fc)r    r   r   rS   r   rU   rT   r   r   r   rV   Úir!   r#   r$   r   Å   sN   

úûÿ
	ûÿ	
ÿzSkiM.__init__c                 C   sj  |j \}}}| jr!t| dd¡| jd\}}| dddd¡ ¡ }n| j|d\}}| |d| j|¡}|j \}}}}|| jks@J ‚| || ||¡ ¡ }d }	t	| j
ƒD ]}
| j|
 ||	ƒ\}}	| jrp|
| j
d k rp| j|
 |	|ƒ}	qR| jr’| ||||¡ dddd¡}t||ƒ}|  |¡ dd¡}|S | ||| |¡d d …d |…d d …f }|  | dd¡¡ dd¡}|S )Nr
   rI   )rT   r   é   )rM   r'   )r   rV   r   r(   rT   Úpermuter)   Ú_padfeaturer*   rY   rU   rX   r   rZ   r   r^   )r    rM   r4   rN   ÚDÚrestr/   ÚKrO   r   r_   r#   r#   r$   r8      s2   
ÿ€
(ýzSkiM.forwardc                 C   sD   |j \}}}| j|| j  }|dkrtjj |ddd|f¡}||fS )Nr   )r   rT   r+   rC   Ú
functionalÚpad)r    rM   r4   rN   rc   rd   r#   r#   r$   rb   "  s
   zSkiM._padfeature)r   rI   rQ   Tr   rR   F)r9   r:   r;   r<   r   r8   rb   r>   r#   r#   r!   r$   rP   ®   s    õ;"rP   Ú__main__iM  éo   éÞ   gš™™™™™¹?r`   rQ   Fr   r	   T)r   rU   rT   r   r   r   rV   rI   iê  )r+   Útorch.nnrC   Úespnet2.enh.layers.dprnnr   r   r   Úespnet2.enh.layers.tcnr   ÚModuler   r?   rP   r9   ÚmodelÚrandnrM   Úprintr   r#   r#   r#   r$   Ú<module>   s.   f;}öñ