o
    
j!                     @   s   d dl Zd dlZd dlmZ d dlmZ z
d dlm	Z	 dZ
W n ey)   dZ
Y nw G dd dZd$d	d
Zd%dejdejfddZ	d&dejdejfddZdd Zdd Zdd Zdd Zdd Zd$ddZd'd d!Zd'd"d#ZdS )(    N)	betabinom)
functional)maximum_path_cTFc                   @   sL   e Zd ZdZddejdejddfddZdd	 Zd
d Zdd Z	dd Z
dS )StandardScalerzQStandardScaler for mean-scale normalization with the given mean and scale values.Nmeanscalereturnc                 C      || _ || _d S Nmean_scale_selfr   r    r   H/home/kuhnn/.local/lib/python3.10/site-packages/TTS/tts/utils/helpers.py__init__      
zStandardScaler.__init__c                 C   r	   r
   r   r   r   r   r   	set_stats   r   zStandardScaler.set_statsc                 C   s   t | d t | d d S )Nr   r   )delattr)r   r   r   r   reset_stats   s   
zStandardScaler.reset_statsc                 C   s"   t |}|| j8 }|| j }|S r
   )npasarrayr   r   r   Xr   r   r   	transform      


zStandardScaler.transformc                 C   s"   t |}|| j9 }|| j7 }|S r
   )r   r   r   r   r   r   r   r   inverse_transform#   r   z StandardScaler.inverse_transform)NN)__name__
__module____qualname____doc__r   ndarrayr   r   r   r   r   r   r   r   r   r      s    r   c                 C   s8   |du r|   }tj|| j| jd}|d| dk S )a  Create a sequence mask for filtering padding in a sequence tensor.

    Args:
        sequence_length (torch.tensor): Sequence lengths.
        max_len (int, Optional): Maximum sequence length. Defaults to None.

    Shapes:
        - mask: :math:`[B, T_max]`
    N)dtypedevicer      )maxtorcharanger#   r$   	unsqueeze)sequence_lengthmax_len	seq_ranger   r   r   sequence_mask+   s   
r-      xsegment_indicesc           	   	   C   s   |r| j d |k rtjj| d|| d f} t| ddddd|f }t| dD ]4}|| }|| }| | }|rW|| dkrWtjj|d|d | d f}|dd||f ||< q/|S )aR  Segment each sample in a batch based on the provided segment indices

    Args:
        x (torch.tensor): Input tensor.
        segment_indices (torch.tensor): Segment indices.
        segment_size (int): Expected output segment size.
        pad_short (bool): Pad the end of input tensor with zeros if shorter than the segment size.
    r      Nr%   )shaper'   nnr   padsize
zeros_likerange)	r/   r0   segment_size	pad_shortsegmentsiindex_start	index_endx_ir   r   r   segment<   s   
 "r@   	x_lengthsc                 C   s   |  }|  \}}}|r||k rtjj| d|| f} |}|du r%|}|| }	|r6|||	dk < || }	nt|	dksFJ d| d| t|g| |	d  	 }
t
| |
||d}||
fS )a  Create random segments based on the input lengths.

    Args:
        x (torch.tensor): Input tensor.
        x_lengths (torch.tensor): Input lengths.
        segment_size (int): Expected output segment size.
        let_short_samples (bool): Allow shorter samples than the segment size.
        pad_short (bool): Pad the end of input tensor with zeros if shorter than the segment size.

    Shapes:
        - x: :math:`[B, C, T]`
        - x_lengths: :math:`[B]`
    r   Nz; [!] At least one sample is shorter than the segment size (z). 
 r%   )r:   )cloner6   r'   r4   r   r5   allrandtype_aslongr@   )r/   rA   r9   let_short_samplesr:   
_x_lenghtsB_Tlen_diffr0   retr   r   r   rand_segmentsV   s(   
rN   c                 C   s  t j|dd }t jj|ddddf d}t jjt j| dkddd}t jjt j| ddd}| \}}| d}|dddddf |||}	|dddddf |||}
t |d|
t |d|	 	 }t |d|
t |d|	 	 }t 
|dk||| }|S )zAverage values over durations.

    Shapes:
        - values: :math:`[B, 1, T_de]`
        - durs: :math:`[B, T_en]`
        - avg: :math:`[B, 1, T_en]`
    r%   )dimNr1   )r%   r   g        r2   )r'   cumsumrF   r4   r   r5   r6   expandgatherfloatwhere)valuesdursdurs_cums_endsdurs_cums_startsvalues_nonzero_cumsvalues_cumsbsl
n_formantsdcsdcevalues_sumsvalues_nelemsavgr   r   r   average_over_durations{   s    
    rc   c                 C   s    | d d d }dd |D } | S )Nr1   c                 S   s   g | ]	}|D ]}|qqS r   r   ).0sublistitemr   r   r   
<listcomp>   s    z%convert_pad_shape.<locals>.<listcomp>r   )	pad_shaper\   r   r   r   convert_pad_shape   s   ri   c              	   C   s   |j \}}}t| d}||| }t|||j}||||}|t|t	ddgddgddggddddf  }|| }|S )z
    Shapes:
        - duration: :math:`[B, T_en]`
        - mask: :math:'[B, T_en, T_de]`
        - path: :math:`[B, T_en, T_de]`
    r%   r   Nr1   )
r3   r'   rP   viewr-   tor#   Fr5   ri   )durationmaskbt_xt_ycum_durationcum_duration_flatpathr   r   r   generate_path   s   6ru   c                 C   s   t rt| |S t| |S r
   )CYTHONmaximum_path_cythonmaximum_path_numpy)valuern   r   r   r   maximum_path   s   

rz   c                 C   s   | | } | j }| j}| j  tj} t| tj	}|j  }|
ddddf tj	}|
ddddf tj	}t|| || t|j||dS )z{Cython optimised version.
    Shapes:
        - value: :math:`[B, T_en, T_de]`
        - mask: :math:`[B, T_en, T_de]`
    r%   Nr   r2   r$   r#   )r$   r#   datacpunumpyastyper   float32r7   int32sumr   r'   
from_numpyrk   )ry   rn   r$   r#   rt   t_x_maxt_y_maxr   r   r   rw      s   rw   c              	   C   s  |du rt j }| | } | j}| j}|    } |   t}| j	\}}}t j
| j	t jd}t j
||ft jd}	t j|t jddd}
t|D ]G}t j|	ddgddggd|dddddf }|	}||k}t |||}||dddd|f< |
|k}t ||| dddd|f  |}	qNt ||d}t j
| j	t jd}|dddddf dt jd }t |}tt|D ]}d||||f< |||||f  d }q||t j }t|j||d}|S )	z
    Monotonic alignment search algorithm
    Numpy-friendly version. It's about 4 times faster than torch version.
    value: [b, t_x, t_y]
    mask: [b, t_x, t_y]
    N)r#   r%   r1   r   constant)modeconstant_valuesr{   )r   infr$   r#   r}   detachr~   r   boolr3   zerosint64r   r(   reshaper8   r5   rT   r   reversedr'   r   rk   )ry   rn   max_neg_valr$   r#   ro   rp   rq   	directionvx_rangejv0v1max_maskv_max
index_maskrt   indexindex_ranger   r   r   rx      s:   .&(
rx         ?c                 C   sr   | |}}t d|}g }td|d D ]}|| ||d |  }}	t|||	}
|
|}|| qt |S )Nr   r%   )r   r(   r8   r   pmfappendarray)phoneme_count	mel_countscaling_factorPMr/   mel_text_probsr<   aro   rv
mel_i_probr   r   r    beta_binomial_prior_distribution   s   


r   c                 C   s   t | ||}|S )z3Compute attention priors for the alignment network.)r   )x_leny_lenr   
attn_priorr   r   r   compute_attn_prior   s   r   r
   )r.   F)Nr.   FF)r   )r~   r   r'   scipy.statsr   torch.nnr   rl   "TTS.tts.utils.monotonic_align.corer   rv   ModuleNotFoundErrorr   r-   tensorr@   rN   rc   ri   ru   rz   rw   rx   r   r   r   r   r   r   <module>   s6    

%

*