o
    ?e'                     @   s   d 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 ddlm	Z	 ddl
mZ dd	lmZ dd
lmZ dd Zedej		dddZdS )zGeneral shape ops for frames.    N)constant_op)ops)tensor_util)	array_ops)math_ops)util_ops)dispatch)	tf_exportc           
      C   s   t |}t |}t |}| jjdu rdS |du r$dg| jjd  S | j }d}|| }|d| }||d dd }	|rl|durl|durU|rUtd| |  }n|durl|durl|raJ td|| | | }|||g |	 S )z0Infers the shape of the return value of `frame`.N   r   )r   constant_valueshapeZndimsas_listmax)
signalframe_length
frame_steppad_endaxissignal_shape
num_framesZ
frame_axisouter_dimensionsinner_dimensions r   g/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/ops/signal/shape_ops.py_infer_frame_shape   s*   



r   zsignal.frameFc           "   	   C   s`  t |d| |||g t j| dd} t j|dd}t j|dd}t j|dd}| jd |jd |jd |jd t| ||||}d	d
 }|t| \}	}
||\}}|
r{|r{tt	|	| }t
j|	||d gd\}}}| }n"t| }t|| }t|	|d|d | g\}}}t|g }t|}t|}|rt || j}|jd | |  }td|||d   | }ttj|dg|jdt d|ggtj|dg|jdgd}tj| ||d} t| }	|	| }nttjd|jdd|| |  }|t||\}}|| }|| }|| }t||| g|gd}t|||g|gd}tt| t|	||}ttj||jd| |dg}ttj||jdd|g}|| }t |}t j||jd}t j||g|jd} ttj|||dt|| |gd}!|r|!| |!W  d   S 1 sw   Y  dS )a/	  Expands `signal`'s `axis` dimension into frames of `frame_length`.

  Slides a window of size `frame_length` over `signal`'s `axis` dimension
  with a stride of `frame_step`, replacing the `axis` dimension with
  `[frames, frame_length]` frames.

  If `pad_end` is True, window positions that are past the end of the `axis`
  dimension are padded with `pad_value` until the window moves fully past the
  end of the dimension. Otherwise, only window positions that fully overlap the
  `axis` dimension are produced.

  For example:

  >>> # A batch size 3 tensor of 9152 audio samples.
  >>> audio = tf.random.normal([3, 9152])
  >>>
  >>> # Compute overlapping frames of length 512 with a step of 180 (frames overlap
  >>> # by 332 samples). By default, only 49 frames are generated since a frame
  >>> # with start position j*180 for j > 48 would overhang the end.
  >>> frames = tf.signal.frame(audio, 512, 180)
  >>> frames.shape.assert_is_compatible_with([3, 49, 512])
  >>>
  >>> # When pad_end is enabled, the final two frames are kept (padded with zeros).
  >>> frames = tf.signal.frame(audio, 512, 180, pad_end=True)
  >>> frames.shape.assert_is_compatible_with([3, 51, 512])

  If the dimension along `axis` is N, and `pad_end=False`, the number of frames
  can be computed by:
   ```python
   num_frames = 1 + (N - frame_size) // frame_step
   ```
   If `pad_end=True`, the number of frames can be computed by:
  ```python
  num_frames = -(-N // frame_step) # ceiling division
  ```

  Args:
    signal: A `[..., samples, ...]` `Tensor`. The rank and dimensions
      may be unknown. Rank must be at least 1.
    frame_length: The frame length in samples. An integer or scalar `Tensor`.
    frame_step: The frame hop size in samples. An integer or scalar `Tensor`.
    pad_end: Whether to pad the end of `signal` with `pad_value`.
    pad_value: An optional scalar `Tensor` to use where the input signal
      does not exist when `pad_end` is True.
    axis: A scalar integer `Tensor` indicating the axis to frame. Defaults to
      the last axis. Supports negative values for indexing from the end.
    name: An optional name for the operation.

  Returns:
    A `Tensor` of frames with shape `[..., num_frames, frame_length, ...]`.

  Raises:
    ValueError: If `frame_length`, `frame_step`, `pad_value`, or `axis` are not
      scalar.
  framer   )namer   r   r   r
   r   c                 S   s"   t | }|d ur|dfS | dfS )NTF)r   r   )valZ
val_staticr   r   r   maybe_constant   s   
zframe.<locals>.maybe_constant)Zindices_or_sections   )dtype)Zconstant_values)r   N)r   Z
name_scopeZconvert_to_tensorr   Zwith_rank_at_leastZassert_has_rankr   r   rangelennpsplititemZrankr   Zreshapesizer!   maximumconcatZzerospadr   Zconstantr   gcdZstrided_sliceZ
zeros_likegather	set_shape)"r   r   r   r   Z	pad_valuer   r   Zresult_shaper   r   Zsignal_shape_is_staticZaxis_is_staticr   Zlength_samplesr   Zsignal_rankZnum_outer_dimensionsZnum_inner_dimensionsr   Zpad_samplesZpaddingsZsubframe_length_Zsubframes_per_frameZsubframes_per_hopZnum_subframesZslice_shapeZsubframe_shapeZ	subframesZframe_selectorZsubframe_selectorselectorZmid_dimensionsframesr   r   r   r   7   s   ;









	


&r   )Fr   r   N)__doc__numpyr$   Ztensorflow.python.frameworkr   r   r   Ztensorflow.python.opsr   r   Ztensorflow.python.ops.signalr   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr	   r   Zadd_dispatch_supportr   r   r   r   r   <module>   s    