o
    i                     @   sP   d Z ddlZddlZddlmZ ddlZddlmZmZ G dd dej	j
ZdS )z^WaveNet modules.

This code is modified from https://github.com/kan-bayashi/ParallelWaveGAN.

    N)Optional)	Conv1d1x1ResidualBlockc                %       s  e Zd ZdZ														
	
				d0dedededededededededededededededededef$ fddZ	 	 	 d1d!ej	d"e
ej	 d#e
ej	 d$e
ej	 d%ej	f
d&d'Zd(d) Zd*d+ Zededededed%ef
d,d-Zed%efd.d/Z  ZS )2WaveNetz!WaveNet with global conditioning.            @              TFin_channelsout_channelskernel_sizelayersstacksbase_dilationresidual_channelsaux_channelsgate_channelsskip_channelsglobal_channelsdropout_ratebiasuse_weight_normuse_first_convuse_last_convscale_residualscale_skip_connectc                    s
  t    || _|| _|| _|| _|| _|| _|| _|| dks"J || }| jr1t	||dd| _
tj | _t|D ]}|||  }t|||	|
||||||d
}|  j|g7  _q;| jr{tjtjjddt	|
|
ddtjjddt	|
|dd| _|r|   dS dS )ai  Initialize WaveNet module.

        Args:
            in_channels (int): Number of input channels.
            out_channels (int): Number of output channels.
            kernel_size (int): Kernel size of dilated convolution.
            layers (int): Number of residual block layers.
            stacks (int): Number of stacks i.e., dilation cycles.
            base_dilation (int): Base dilation factor.
            residual_channels (int): Number of channels in residual conv.
            gate_channels (int):  Number of channels in gated conv.
            skip_channels (int): Number of channels in skip conv.
            aux_channels (int): Number of channels for local conditioning feature.
            global_channels (int): Number of channels for global conditioning feature.
            dropout_rate (float): Dropout rate. 0.0 means no dropout applied.
            bias (bool): Whether to use bias parameter in conv layer.
            use_weight_norm (bool): Whether to use weight norm. If set to true, it will
                be applied to all of the conv layers.
            use_first_conv (bool): Whether to use the first conv layers.
            use_last_conv (bool): Whether to use the last conv layers.
            scale_residual (bool): Whether to scale the residual outputs.
            scale_skip_connect (bool): Whether to scale the skip connection outputs.

        r   T)r   )
r   r   r   r   r   r   dilationr   r   r   )inplaceN)super__init__r   r   r   r   r   r   r   r   
first_convtorchnn
ModuleListconv_layersranger   
SequentialReLU	last_convapply_weight_norm)selfr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   layers_per_stacklayerr    conv	__class__ S/home/ubuntu/.local/lib/python3.10/site-packages/espnet2/gan_tts/wavenet/wavenet.pyr#      sL   
-zWaveNet.__init__Nxx_maskcgreturnc                 C   sr   | j r| |}d}| jD ]}|||||d\}}|| }q|}| jr/|tdt| j  }| jr7| |}|S )a"  Calculate forward propagation.

        Args:
            x (Tensor): Input noise signal (B, 1, T) if use_first_conv else
                (B, residual_channels, T).
            x_mask (Optional[Tensor]): Mask tensor (B, 1, T).
            c (Optional[Tensor]): Local conditioning features (B, aux_channels, T).
            g (Optional[Tensor]): Global conditioning features (B, global_channels, 1).

        Returns:
            Tensor: Output tensor (B, out_channels, T) if use_last_conv else
                (B, residual_channels, T).

        r   )r7   r8   r9   g      ?)	r   r$   r(   r   mathsqrtlenr   r,   )r.   r6   r7   r8   r9   skipsfhr4   r4   r5   forwards   s   



zWaveNet.forwardc                 C       dt jjfdd}| | dS )z:Remove weight normalization module from all of the layers.mc                 S   s<   zt d|  d tjj|  W d S  ty   Y d S w )NzWeight norm is removed from .)loggingdebugr%   r&   utilsremove_weight_norm
ValueErrorrC   r4   r4   r5   _remove_weight_norm   s   z7WaveNet.remove_weight_norm.<locals>._remove_weight_normNr%   r&   Moduleapply)r.   rK   r4   r4   r5   rH      s   zWaveNet.remove_weight_normc                 C   rB   )z9Apply weight normalization module from all of the layers.rC   c                 S   sD   t | tjjst | tjjr tjj|  td|  d d S d S )NzWeight norm is applied to rD   )	
isinstancer%   r&   Conv1dConv2drG   weight_normrE   rF   rJ   r4   r4   r5   _apply_weight_norm   s   z5WaveNet.apply_weight_norm.<locals>._apply_weight_normNrL   )r.   rS   r4   r4   r5   r-      s   zWaveNet.apply_weight_normc                    sD   | | dksJ | |  fddt | D }|d t| d S )Nr   c                    s   g | ]} |  qS r4   r4   ).0ir   layers_per_cycler4   r5   
<listcomp>   s    z5WaveNet._get_receptive_field_size.<locals>.<listcomp>r   )r)   sum)r   r   r   r   	dilationsr4   rV   r5   _get_receptive_field_size   s   z!WaveNet._get_receptive_field_sizec                 C   s   |  | j| j| j| jS )zReturn receptive field size.)r[   r   r   r   r   )r.   r4   r4   r5   receptive_field_size   s   zWaveNet.receptive_field_size)r   r   r   r   r   r	   r
   r   r   r
   r   r   TTFFFF)NNN)__name__
__module____qualname____doc__intfloatboolr#   r%   Tensorr   rA   rH   r-   staticmethodr[   propertyr\   __classcell__r4   r4   r2   r5   r      s    	
`
(
r   )r`   rE   r;   typingr   r%   &espnet2.gan_tts.wavenet.residual_blockr   r   r&   rM   r   r4   r4   r4   r5   <module>   s   