
    0;ji                         d dl Z 	 d e j        d          fdededede j        de j        f
d	Z	 dde j        de j        dedededededefdZdde j        dede j        fdZdS )    Ncpusize
chunk_sizenum_left_chunksdevicereturnc                     t          j        | |          }t          j        ||d          dz   |z  }|                    d          |                    d          k     }|S )a7  Create mask for subsequent steps (size, size) with chunk size,
       this is for streaming encoder

    Args:
        size (int): size of mask
        chunk_size (int): size of chunk
        num_left_chunks (int): number of left chunks
            <0: use full chunk
            >=0: use num_left_chunks
        device (torch.device): "cpu" or "cuda" or torch.Tensor.device

    Returns:
        torch.Tensor: mask

    Examples:
        >>> subsequent_chunk_mask(4, 2)
        [[1, 1, 0, 0],
         [1, 1, 0, 0],
         [1, 1, 1, 1],
         [1, 1, 1, 1]]
    )r   trunc)rounding_mode   r   )torcharangediv	unsqueeze)r   r   r   r   pos_idxblock_valuerets          \/root/voice-cloning/.venv/lib/python3.11/site-packages/chatterbox/models/s3gen/utils/mask.pysubsequent_chunk_maskr   6   sd    : l4///G9WjHHH1LPZZK


A

!6!6q!9!9
9CJ    Txsmasksuse_dynamic_chunkuse_dynamic_left_chunkdecoding_chunk_sizestatic_chunk_sizenum_decoding_left_chunksenable_full_contextc                    |r|                      d          }|dk     r|}	d}
n}|dk    r|}	|}
nrt          j        d|d                                          }	d}
|	|dz  k    r|r|}	n:|	dz  dz   }	|r0|dz
  |	z  }t          j        d|d                                          }
t	          |                      d          |	|
| j                  }|                    d          }||z  }nO|dk    rG|}
t	          |                      d          ||
| j                  }|                    d          }||z  }n|}|j        t          j        k    sJ |	                    d          dk    	                                                                dk    r7t                              d           d	||	                    d          dk    <   |S )
a   Apply optional mask for encoder.

    Args:
        xs (torch.Tensor): padded input, (B, L, D), L for max length
        mask (torch.Tensor): mask for xs, (B, 1, L)
        use_dynamic_chunk (bool): whether to use dynamic chunk or not
        use_dynamic_left_chunk (bool): whether to use dynamic left chunk for
            training.
        decoding_chunk_size (int): decoding chunk size for dynamic chunk, it's
            0: default for training, use random dynamic chunk.
            <0: for decoding, use full chunk.
            >0: for decoding, use fixed chunk size as set.
        static_chunk_size (int): chunk size for static chunk training/decoding
            if it's greater than 0, if use_dynamic_chunk is true,
            this parameter will be ignored
        num_decoding_left_chunks: number of left chunks, this is for decoding,
            the chunk size is decoding_chunk_size.
            >=0: use num_decoding_left_chunks
            <0: use all left chunks
        enable_full_context (bool):
            True: chunk size is either [1, 25] or full context(max_len)
            False: chunk size ~ U[1, 25]

    Returns:
        torch.Tensor: chunk mask of the input xs.
    r   r   r   )r         )dimzoget chunk_masks all false at some timestep, force set to true, make sure they are masked in futuer computation!T)r   r   randintitemr   r   r   dtypeboolsumloggingwarning)r   r   r   r   r   r   r   r   max_lenr   r   max_left_chunkschunk_maskss                r   add_optional_chunk_maskr.   Y   s   F  #''!**"" J OO 1$$,J6OO
 q'599>>@@J OGqL((-@($

'"_q0
) B'.{z&AO&+mA49'; ';;?466 $+BGGAJJ
,;,.I7 7 "++A..k)	Q		2+BGGAJJ8I,;,.I7 7 "++A..k)
****B1$))++0022a77  J  	K  	K  	K26KOOO++Q./r   lengthsr+   c                    |                                  } |                     d          }|dk    r|n%|                                                                 }t	          j        d|t          j        | j                  }|                    d          	                    ||          }|                     d          }||k    }|S )a  Make mask tensor containing indices of padded part.

    See description of make_non_pad_mask.

    Args:
        lengths (torch.Tensor): Batch of lengths (B,).
    Returns:
        torch.Tensor: Mask tensor containing indices of padded part.

    Examples:
        >>> lengths = [5, 3, 2]
        >>> make_pad_mask(lengths)
        masks = [[0, 0, 0, 0 ,0],
                 [0, 0, 0, 1, 1],
                 [0, 0, 1, 1, 1]]
    r   )r&   r   r   )
longr   maxr%   r   r   int64r   r   expand)r/   r+   
batch_size	seq_rangeseq_range_expandseq_length_expandmasks          r   make_pad_maskr:      s    " llnnGaJ 1gg'++--*<*<*>*>GQ$#(;$+N4 4 4I !**1--44ZII))"--00DKr   )T)r   )r   r   intTensorr   r'   r.   r:    r   r   <module>r>      s+  "  L  "+u|E22	        	 
 \       T 9=K K K#(<K/3K 59K 25	K
 03K 7:K 26K K K K\ 5< # el      r   