o
    
j                     @   s`   d dl Z d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ G dd dejjZdS )    N)remove_parametrizations)load_fsspec)ResidualBlock)ConvUpsamplec                       s   e Zd ZdZddddddddddd	d	g d
df fdd	Zdd Ze dd Zdd Z	dd Z
edd fddZedd Z	dddZ  ZS ) ParallelWaveganGeneratorzPWGAN generator as in https://arxiv.org/pdf/1910.11480.pdf.
    It is similar to WaveNet with no causal convolution.
        It is conditioned on an aux feature (spectrogram) to generate
    an output waveform from an input noise.
             @      P   g        T)   r   r   r      c                    s2  t    || _|| _|	| _|| _|| _|| _|| _t	
|| _|| _|| _|| dks.J || }tjj||ddd| _t|d| _tj | _t|D ]}d||  }t|||||	||
|d}|  j|g7  _qMtjtjjddtjj||dddtjjddtjj||dddg| _|r|   d S d S )	Nr   r   T)kernel_sizebias)upsample_factorsr   )r   res_channelsgate_channelsskip_channelsaux_channelsdilationdropoutr   )inplace)super__init__in_channelsout_channelsr   num_res_blocksstacksr   r   npprodupsample_scaleinference_paddinguse_weight_normtorchnnConv1d
first_convr   upsample_net
ModuleListconv_layersranger   ReLUlast_conv_layersapply_weight_norm)selfr   r   r   r   r   r   r   r   r   r   r   r#   r   r"   layers_per_stacklayerr   conv	__class__ `/home/kuhnn/.local/lib/python3.10/site-packages/TTS/vocoder/models/parallel_wavegan_generator.pyr      sN   


z!ParallelWaveganGenerator.__init__c                 C   s   t |jd d|jd | j g}|| jjj}|dur=| jdur=| |}|jd |jd ks=J d|j d|j | |}d}| j	D ]}|||\}}||7 }qG|t
dt| j	 9 }|}| jD ]}||}qf|S )	zN
        c: (B, C ,T').
        o: Output tensor (B, out_channels, T)
        r   r   r   Nz: [!] Upsampling scale does not match the expected output. z vs g      ?)r$   randnshaper!   tor'   r   devicer(   r*   mathsqrtlenr-   )r/   cxskipsfhr5   r5   r6   forwardY   s"   "





z ParallelWaveganGenerator.forwardc                 C   s4   | | jjj}tjj|| j| jfd}| 	|S )N	replicate)
r:   r'   weightr;   r$   r%   
functionalpadr"   rD   )r/   r?   r5   r5   r6   	inferencex   s   
z"ParallelWaveganGenerator.inferencec                 C      dd }|  | d S )Nc                 S   s&   zt | d W d S  ty   Y d S w )NrF   )r   
ValueErrormr5   r5   r6   _remove_weight_norm   s
   zHParallelWaveganGenerator.remove_weight_norm.<locals>._remove_weight_normapply)r/   rN   r5   r5   r6   remove_weight_norm~   s   z+ParallelWaveganGenerator.remove_weight_normc                 C   rJ   )Nc                 S   s.   t | tjjtjjfrtjjj|  d S d S N)
isinstancer$   r%   r&   Conv2dutilsparametrizationsweight_normrL   r5   r5   r6   _apply_weight_norm   s   zFParallelWaveganGenerator.apply_weight_norm.<locals>._apply_weight_normrO   )r/   rX   r5   r5   r6   r.      s   z*ParallelWaveganGenerator.apply_weight_normc                 C   s   d|  S )Nr   r5   )r@   r5   r5   r6   <lambda>   s    z!ParallelWaveganGenerator.<lambda>c                    sD   | | dksJ | |  fddt | D }|d t| d S )Nr   c                    s   g | ]} | qS r5   r5   ).0ir   layers_per_cycler5   r6   
<listcomp>   s    zFParallelWaveganGenerator._get_receptive_field_size.<locals>.<listcomp>r   )r+   sum)layersr   r   r   	dilationsr5   r\   r6   _get_receptive_field_size   s   z2ParallelWaveganGenerator._get_receptive_field_sizec                 C   s   |  | j| j| jS rR   )rb   r`   r   r   )r/   r5   r5   r6   receptive_field_size   s   z-ParallelWaveganGenerator.receptive_field_sizeFc                 C   sR   t |td|d}| |d  |r%|   | jrJ | jr'|   d S d S d S )Ncpu)map_locationcachemodel)r   r$   r;   load_state_dictevaltrainingr#   rQ   )r/   configcheckpoint_pathri   rf   stater5   r5   r6   load_checkpoint   s   
z(ParallelWaveganGenerator.load_checkpoint)FF)__name__
__module____qualname____doc__r   rD   r$   no_gradrI   rQ   r.   staticmethodrb   propertyrc   rn   __classcell__r5   r5   r3   r6   r      s8    	E


r   )r<   numpyr   r$   torch.nn.utils.parametrizer   TTS.utils.ior   #TTS.vocoder.layers.parallel_waveganr   TTS.vocoder.layers.upsampler   r%   Moduler   r5   r5   r5   r6   <module>   s    