
    yj^                        d dl mZ d dlmZmZ d dlZd dlmZ d dlmZm	Z	m
Z
 ddlmZ ddlmZ dd	lmZmZmZ dd
lmZ erd dlmZ ed         ZddgZ	 	 d/d0dZ	 d/d1dZ	 	 	 	 	 	 	 	 d2d3d+Z	 	 	 	 	 	 	 	 	 d4d5d.ZdS )6    )annotations)TYPE_CHECKINGLiteralN)_C_ops)in_dynamic_modein_dynamic_or_pir_modein_pir_mode   )check_variable_and_dtype)LayerHelper)fft_c2cfft_c2rfft_r2c)
is_complex)Tensorr   stftistftr   xr   frame_lengthint
hop_lengthaxis_SignalAxesname
str | Nonereturnc                   |dvrt          d| d          t          |t                    r|dk    rt          d| d          t          |t                    r|dk    rt          d| d          t                      rI|| j        |         k    r!t          d| d	| j        |          d
          t          j        | |||          S t                      rt          j        | |||          S d}t          | dg d|           t          |fi t                      }|                    d          }|                    |          }|                    |d| i|||dd|i           |S )a  
    Slice the N-dimensional (where N >= 1) input into (overlapping) frames.

    Args:
        x (Tensor): The input data which is a N-dimensional (where N >= 1) Tensor
            with shape `[..., seq_length]` or `[seq_length, ...]`.
        frame_length (int): Length of the frame and `0 < frame_length <= x.shape[axis]`.
        hop_length (int): Number of steps to advance between adjacent frames
            and `0 < hop_length`.
        axis (int, optional): Specify the axis to operate on the input Tensors. Its
            value should be 0(the first dimension) or -1(the last dimension). If not
            specified, the last axis is used by default.
        name (str|None, optional): The default value is None. Normally there is no need for user
            to set this property. For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        The output frames tensor with shape `[..., frame_length, num_frames]` if `axis==-1`,
            otherwise `[num_frames, frame_length, ...]` where

            `num_frames = 1 + (x.shape[axis] - frame_length) // hop_length`

    Examples:

        .. code-block:: pycon

            >>> import paddle
            >>> from paddle import signal

            >>> # 1D
            >>> x = paddle.arange(8)
            >>> y0 = signal.frame(x, frame_length=4, hop_length=2, axis=-1)
            >>> print(y0)
            Tensor(shape=[4, 3], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[0, 2, 4],
             [1, 3, 5],
             [2, 4, 6],
             [3, 5, 7]])

            >>> y1 = signal.frame(x, frame_length=4, hop_length=2, axis=0)
            >>> print(y1)
            Tensor(shape=[3, 4], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[0, 1, 2, 3],
             [2, 3, 4, 5],
             [4, 5, 6, 7]])

            >>> # 2D
            >>> x0 = paddle.arange(16).reshape([2, 8])
            >>> y0 = signal.frame(x0, frame_length=4, hop_length=2, axis=-1)
            >>> print(y0)
            Tensor(shape=[2, 4, 3], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[[0 , 2 , 4 ],
              [1 , 3 , 5 ],
              [2 , 4 , 6 ],
              [3 , 5 , 7 ]],
             [[8 , 10, 12],
              [9 , 11, 13],
              [10, 12, 14],
              [11, 13, 15]]])

            >>> x1 = paddle.arange(16).reshape([8, 2])
            >>> y1 = signal.frame(x1, frame_length=4, hop_length=2, axis=0)
            >>> print(y1.shape)
            paddle.Size([3, 4, 2])

            >>> # > 2D
            >>> x0 = paddle.arange(32).reshape([2, 2, 8])
            >>> y0 = signal.frame(x0, frame_length=4, hop_length=2, axis=-1)
            >>> print(y0.shape)
            paddle.Size([2, 2, 4, 3])

            >>> x1 = paddle.arange(32).reshape([8, 2, 2])
            >>> y1 = signal.frame(x1, frame_length=4, hop_length=2, axis=0)
            >>> print(y1.shape)
            paddle.Size([3, 4, 2, 2])
    r   Unexpected axis: . It should be 0 or -1.r   zUnexpected frame_length: #. It should be an positive integer.Unexpected hop_length: zKAttribute frame_length should be less equal than sequence length, but got (z) > (z).framer   )int32int64float16float32float64input_param_namedtypeX)r   r   r   Outtypeinputsattrsoutputs)
ValueError
isinstancer   r   shaper   r$   r	   r   r   localsinput_dtype"create_variable_for_type_inference	append_op)	r   r   r   r   r   op_typehelperr-   outs	            ]/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/signal.pyr$   r$   *   s   d 7JTJJJKKKlC(( 
LA,=,=YYYY
 
 	
 j#&& 
*//UjUUU
 
 	
  
!'$-''A(A A/0wt}A A A   |A|Z>>>	 
|A|Z>>> sGGG	
 	
 	
 W1111""C"8877e7DD8 ,( 
 CL 	 		
 		
 		
 J    c                   |dvrt          d| d          t          |t                    r|dk    rt          d| d          d}t                      rt	          j        | ||          }nyt          | dg d	|           t          |fi t                      }|	                    d
          }|
                    |          }|                    |d| i||dd|i           |S )aa
  
    Reconstructs a tensor consisted of overlap added sequences from input frames.

    Args:
        x (Tensor): The input data which is a N-dimensional (where N >= 2) Tensor
            with shape `[..., frame_length, num_frames]` or
            `[num_frames, frame_length ...]`.
        hop_length (int): Number of steps to advance between adjacent frames and
            `0 < hop_length <= frame_length`.
        axis (int, optional): Specify the axis to operate on the input Tensors. Its
            value should be 0(the first dimension) or -1(the last dimension). If not
            specified, the last axis is used by default.
        name (str|None, optional): The default value is None. Normally there is no need for user
            to set this property. For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        The output frames tensor with shape `[..., seq_length]` if `axis==-1`,
            otherwise `[seq_length, ...]` where

            `seq_length = (n_frames - 1) * hop_length + frame_length`

    Examples:

        .. code-block:: pycon

            >>> import paddle
            >>> from paddle.signal import overlap_add

            >>> # 2D
            >>> x0 = paddle.arange(16).reshape([8, 2])
            >>> print(x0)
            Tensor(shape=[8, 2], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[0 , 1 ],
             [2 , 3 ],
             [4 , 5 ],
             [6 , 7 ],
             [8 , 9 ],
             [10, 11],
             [12, 13],
             [14, 15]])


            >>> y0 = overlap_add(x0, hop_length=2, axis=-1)
            >>> print(y0)
            Tensor(shape=[10], dtype=int64, place=Place(cpu), stop_gradient=True,
            [0 , 2 , 5 , 9 , 13, 17, 21, 25, 13, 15])

            >>> x1 = paddle.arange(16).reshape([2, 8])
            >>> print(x1)
            Tensor(shape=[2, 8], dtype=int64, place=Place(cpu), stop_gradient=True,
            [[0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ],
             [8 , 9 , 10, 11, 12, 13, 14, 15]])


            >>> y1 = overlap_add(x1, hop_length=2, axis=0)
            >>> print(y1)
            Tensor(shape=[10], dtype=int64, place=Place(cpu), stop_gradient=True,
            [0 , 1 , 10, 12, 14, 16, 18, 20, 14, 15])


            >>> # > 2D
            >>> x0 = paddle.arange(32).reshape([2, 1, 8, 2])
            >>> y0 = overlap_add(x0, hop_length=2, axis=-1)
            >>> print(y0.shape)
            paddle.Size([2, 1, 10])

            >>> x1 = paddle.arange(32).reshape([2, 8, 1, 2])
            >>> y1 = overlap_add(x1, hop_length=2, axis=0)
            >>> print(y1.shape)
            paddle.Size([10, 1, 2])
    r   r    r!   r   r#   r"   overlap_addr   )r%   r&   r'   r(   r)   uint16r*   r,   r.   )r   r   r/   r0   )r5   r6   r   r   r   rB   r   r   r8   r9   r:   r;   )r   r   r   r   r<   r>   r=   r-   s           r?   rB   rB      s:   T 7JTJJJKKKj#&& 
*//UjUUU
 
 	
 G 
 J55 III		
 	
 	
 W1111""C"8877e7DD8!+T::CL	 	 	
 	
 	
 Jr@   TreflectFn_fft
int | None
win_lengthwindowTensor | Nonecenterboolpad_modeLiteral['reflect', 'constant']
normalizedonesidedbool | Nonec
           	     x   t          | j                  }
|
dv sJ d|
             |
dk    r|                     d          } |t          |dz            }|dk    sJ d| d            ||}t	                      r6d|cxk     r| j        d	         k    sn J d
| j        d	          d| d            d|cxk     r|k    sn J d| d| d            |Bt          |j                  dk    rt          |          |k    sJ d| d|j         d            nt          j        |f| j                  }||k     r9||z
  dz  }||z
  |z
  }t
          j        j	        
                    |||gd          }|rg|dv sJ d| d            |dz  }t
          j        j	        
                    |                     d	          ||g|d                              d	          } t          | ||d	          }|                    g d          }t          j        ||          }|rdnd}|t          |           }t          |          r|r
J d            t          |           st!          |dd	|d||	          }nt#          |dd	|d|	           }|                    g d          }|
dk    r|                    d           |S )!a  

    Short-time Fourier transform (STFT).

    The STFT computes the discrete Fourier transforms (DFT) of short overlapping
    windows of the input using this formula:

    .. math::
        X_t[f] = \sum_{n = 0}^{N-1} \text{window}[n]\ x[t \times H + n]\ e^{-{2 \pi j f n}/{N}}

    Where:
    - :math:`t`: The :math:`t`-th input window.
    - :math:`f`: Frequency :math:`0 \leq f < \text{n_fft}` for `onesided=False`,
    or :math:`0 \leq f < \lfloor \text{n_fft} / 2 \rfloor + 1` for `onesided=True`.
    - :math:`N`: Value of `n_fft`.
    - :math:`H`: Value of `hop_length`.

    Args:
        x (Tensor): The input data which is a 1-dimensional or 2-dimensional Tensor with
            shape `[..., seq_length]`. It can be a real-valued or a complex Tensor.
        n_fft (int): The number of input samples to perform Fourier transform.
        hop_length (int|None, optional): Number of steps to advance between adjacent windows
            and `0 < hop_length`. Default: `None` (treated as equal to `n_fft//4`)
        win_length (int|None, optional): The size of window. Default: `None` (treated as equal
            to `n_fft`)
        window (Tensor|None, optional): A 1-dimensional tensor of size `win_length`. It will
            be center padded to length `n_fft` if `win_length < n_fft`. Default: `None` (
            treated as a rectangle window with value equal to 1 of size `win_length`).
        center (bool, optional): Whether to pad `x` to make that the
            :math:`t \times hop\_length` at the center of :math:`t`-th frame. Default: `True`.
        pad_mode (str, optional): Choose padding pattern when `center` is `True`. See
            `paddle.nn.functional.pad` for all padding options. Default: `"reflect"`
        normalized (bool, optional): Control whether to scale the output by `1/sqrt(n_fft)`.
            Default: `False`
        onesided (bool, optional): Control whether to return half of the Fourier transform
            output that satisfies the conjugate symmetry condition when input is a real-valued
            tensor. It can not be `True` if input is a complex tensor. Default: `None`
        name (str|None, optional): The default value is None. Normally there is no need for user
            to set this property. For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        The complex STFT output tensor with shape `[..., n_fft//2 + 1, num_frames]`
        (real-valued input and `onesided` is `True`) or `[..., n_fft, num_frames]`
        (`onesided` is `False`)

    Examples:
        .. code-block:: pycon

            >>> import paddle
            >>> from paddle.signal import stft

            >>> # real-valued input
            >>> x = paddle.randn([8, 48000], dtype=paddle.float64)
            >>> y1 = stft(x, n_fft=512)
            >>> print(y1.shape)
            paddle.Size([8, 257, 376])

            >>> y2 = stft(x, n_fft=512, onesided=False)
            >>> print(y2.shape)
            paddle.Size([8, 512, 376])

            >>> # complex input
            >>> x = paddle.randn([8, 48000], dtype=paddle.float64) + \
            ...         paddle.randn([8, 48000], dtype=paddle.float64)*1j
            >>> print(x.shape)
            paddle.Size([8, 48000])
            >>> print(x.dtype)
            paddle.complex128

            >>> y1 = stft(x, n_fft=512, center=False, onesided=False)
            >>> print(y1.shape)
            paddle.Size([8, 512, 372])

    )r
      z9x should be a 1D or 2D real tensor, but got rank of x is r
   r   N   z"hop_length should be > 0, but got .r   z"n_fft should be in (0, seq_length()], but got "win_length should be in (0, n_fft(8expected a 1D window tensor of size equal to win_length(), but got window with shape r7   r-   rR   constantpadmode)rZ   rD   z5pad_mode should be "reflect" or "constant", but got "z".NLC)r\   r]   data_format)r   r   r   r   r   rR   r
   permorthobackwardzBonesided should be False when input or window is a complex Tensor.T)r   nr   normforwardrO   r   r   re   r   rf   rg   r   )lenr7   	unsqueezer   r   paddleonesr-   nn
functionalr\   squeezer$   	transposemultiplyr   r   r   squeeze_)r   rE   r   rG   rH   rJ   rL   rN   rO   r   x_rankpad_left	pad_right
pad_lengthx_framesrf   r>   s                    r?   r   r     s   n \\F     L6KK  
 {{KKNN!__
>>>M
MMM>>>
 
5''''AGBK'''''RRR%RRR ('' z""""U"""""MUMM
MMM #"" 6<  A%%#f++*C*C*Czpvp| +D*CC*C J=@@@EJ&1,J&1	%))9-J * 
 
   
 
 
 
 P8OOO
 
 

 aZ
I $$KKOOZ(	 % 
 

 '"++ 	
 qu"MMMH!!YY "  H x00H 077jD!(+++( 
 	
 	
P	
 	
| a== 

 
 
 $RdDt
 
 
 --YYY-
'
'C{{QJr@   lengthreturn_complexc                   t          | dddgd           t          | j                  }|dv sJ d|             |dk    r|                     d          } |t	          |d
z            }||}d|cxk     r|k    sn J d| d| d            d|cxk     r|k    sn J d| d| d            | j        d         }| j        d         }t                      rR| j        dk    s
J d            |r$||dz  dz   k    sJ d|dz  dz    d| d            n||k    sJ d| d| d            |Bt          |j                  dk    rt          |          |k    sJ d| d|j         d            nN| j        t          j	        t          j
        fv rt          j	        nt          j        }t          j        |f|          }||k     r9||z
  dz  }||z
  |z
  }t          j        j                            |||gd          }|                     g d          } |rdnd}|	r"|r
J d             t#          | d	d|d!d	"          }nIt%          |          r
J d#            |d!u r| d	d	d	d	d	|dz  dz   f         } t'          | d	d|d!d	"          }t          j        ||                              g d          }t+          ||d$          }t+          t          j        t          j        ||                              d          |dg%                              ddg          |d$          }|)|r&|d	d	|dz  |dz   f         }||dz  |dz            }n(|r|dz  }nd}|d	d	|||z   f         }||||z            }t                      rK|                                                                                                d&k     rt5          d'          ||z  }|dk    rt          j        |d(          }|S ))a$  
    Inverse short-time Fourier transform (ISTFT).

    Reconstruct time-domain signal from the giving complex input and window tensor when
    nonzero overlap-add (NOLA) condition is met:

    .. math::
        \sum_{t = -\infty}^{\infty} \text{window}^2[n - t \times H]\ \neq \ 0, \ \text{for } all \ n

    Where:
    - :math:`t`: The :math:`t`-th input window.
    - :math:`N`: Value of `n_fft`.
    - :math:`H`: Value of `hop_length`.

        Result of `istft` expected to be the inverse of `paddle.signal.stft`, but it is
        not guaranteed to reconstruct a exactly realizable time-domain signal from a STFT
        complex tensor which has been modified (via masking or otherwise). Therefore, `istft`
        gives the `[Griffin-Lim optimal estimate] <https://ieeexplore.ieee.org/document/1164317>`_
        (optimal in a least-squares sense) for the corresponding signal.

    Args:
        x (Tensor): The input data which is a 2-dimensional or 3-dimensional **complex**
            Tensor with shape `[..., n_fft, num_frames]`.
        n_fft (int): The size of Fourier transform.
        hop_length (int|None, optional): Number of steps to advance between adjacent windows
            from time-domain signal and `0 < hop_length < win_length`. Default: `None` (
            treated as equal to `n_fft//4`)
        win_length (int|None, optional): The size of window. Default: `None` (treated as equal
            to `n_fft`)
        window (Tensor|None, optional): A 1-dimensional tensor of size `win_length`. It will
            be center padded to length `n_fft` if `win_length < n_fft`. It should be a
            real-valued tensor if `return_complex` is False. Default: `None`(treated as
            a rectangle window with value equal to 1 of size `win_length`).
        center (bool, optional): It means that whether the time-domain signal has been
            center padded. Default: `True`.
        normalized (bool, optional): Control whether to scale the output by :math:`1/sqrt(n_{fft})`.
            Default: `False`
        onesided (bool, optional): It means that whether the input STFT tensor is a half
            of the conjugate symmetry STFT tensor transformed from a real-valued signal
            and `istft` will return a real-valued tensor when it is set to `True`.
            Default: `True`.
        length (int|None, optional): Specify the length of time-domain signal. Default: `None`(
            treated as the whole length of signal).
        return_complex (bool, optional): It means that whether the time-domain signal is
            real-valued. If `return_complex` is set to `True`, `onesided` should be set to
            `False` cause the output is complex.
        name (str|None, optional): The default value is None. Normally there is no need for user
            to set this property. For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        A tensor of least squares estimation of the reconstructed signal(s) with shape
        `[..., seq_length]`

    Examples:
        .. code-block:: pycon

            >>> import numpy as np
            >>> import paddle
            >>> from paddle.signal import stft, istft

            >>> paddle.seed(0)

            >>> # STFT
            >>> x = paddle.randn([8, 48000], dtype=paddle.float64)
            >>> y = stft(x, n_fft=512)
            >>> print(y.shape)
            paddle.Size([8, 257, 376])

            >>> # ISTFT
            >>> x_ = istft(y, n_fft=512)
            >>> print(x_.shape)
            paddle.Size([8, 48000])

            >>> np.allclose(x, x_)
            True
    r   	complex64
complex128r   )rR      z<x should be a 2D or 3D complex tensor, but got rank of x is rR   r   NrS   z'hop_length should be in (0, win_length(rU   rT   rV   r   z x should not be an empty tensor.r
   z+fft_size should be equal to n_fft // 2 + 1(z!) when onesided is True, but got z"fft_size should be equal to n_fft(z") when onesided is False, but got rW   rX   rY   rZ   r[   r`   ra   rc   rd   zSonesided should be False when input(output of istft) or window is a complex Tensor.Frh   zGData type of window should not be complex when return_complex is False.)r   r   r   )r   repeat_timesgdy=zAbort istft because Nonzero Overlap Add (NOLA) condition failed. For more information about NOLA constraint please see `scipy.signal.check_NOLA`(https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.check_NOLA.html).)r   )r   ri   r7   rj   r   r   sizer-   rk   r(   r{   r)   rl   rm   rn   r\   rp   r   r   r   rq   rB   tileabsminitemr5   ro   )r   rE   r   rG   rH   rJ   rN   rO   rx   ry   r   rs   n_framesfft_sizewindow_dtypert   ru   rf   r>   window_envelopstarts                        r?   r   r     s~   r Qk<%@'JJJ\\F     OfNN  
 {{KKNN!__

 z''''Z'''''W*WW*WWW ('' z""""U"""""MUMM
MMM #"" wr{Hwr{H 	v{{{>{{{ 	uzA~---zeqj1nzzowzzz .--- u$$$iUii^fiii %$$ 6<  A%%#f++*C*C*Czpvp| +D*CC*C w6>6+;<<< NN 	
 J=EEEEJ&1,J&1	%))9-J * 
 
 	
YY 	 	 	A !077jD Q 	
 	
a	
 	
| Tu4PPPf%% 	
 	
U	
 	
% u!!!QQQ(%1*q.(()ATu4PPP
/#v
&
&
0
0YY 1  C 
*2  C !
+off--77::"A
 
 
 )!Q)
 
   N ~ 	Jaaa%1*%1*556C+UaZUaZ=,HIN 	QJEEE!!!UUV^++,'(>?  
^//115577<<>>FF s
 
 	
 
C{{nSq)))Jr@   )r   N)r   r   r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )NNNTrD   FNN)r   r   rE   r   r   rF   rG   rF   rH   rI   rJ   rK   rL   rM   rN   rK   rO   rP   r   r   r   r   )	NNNTFTNFN)r   r   rE   r   r   rF   rG   rF   rH   rI   rJ   rK   rN   rK   rO   rK   rx   rF   ry   rK   r   r   r   r   )
__future__r   typingr   r   rk   r   paddle.frameworkr   r   r	   base.data_feederr   base.layer_helperr   fftr   r   r   tensor.attributer   r   r   __all__r$   rB   r   r    r@   r?   <module>r      s   # " " " " " ) ) ) ) ) ) ) )                 7 6 6 6 6 6 * * * * * * * * * * * * * * * * ( ( ( ( ( ( !%.K  z z z z z| LPf f f f fX "! /8 r r r r rp "!  Q Q Q Q Q Q Qr@   