
    mi                     Z   d Z ddlZddlmZm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
ej                  j                         Z G d dej                  j                         Z	 	 ddej&                  dee   dedededee   fdZ	 	 ddej&                  dededededee   fdZy)z$
FIR windowed sinc lowpass filters.
    N)SequenceOptional)
functional   )sinc)
fft_conv1dsimple_reprc                   V     e Zd ZdZ	 	 d
dee   dedededee   f
 fdZ	d Z
d	 Z xZS )LowPassFiltersa
  
    Bank of low pass filters. Note that a high pass or band pass filter can easily
    be implemented by substracting a same signal processed with low pass filters with different
    frequencies (see `julius.bands.SplitBands` for instance).
    This uses a windowed sinc filter, very similar to the one used in
    `julius.resample`. However, because we do not change the sample rate here,
    this filter can be much more efficiently implemented using the FFT convolution from
    `julius.fftconv`.

    Args:
        cutoffs (list[float]): list of cutoff frequencies, in [0, 0.5] expressed as `f/f_s` where
            f_s is the samplerate and `f` is the cutoff frequency.
            The upper limit is 0.5, because a signal sampled at `f_s` contains only
            frequencies under `f_s / 2`.
        stride (int): how much to decimate the output. Keep in mind that decimation
            of the output is only acceptable if the cutoff frequency is under `1/ (2 * stride)`
            of the original sampling rate.
        pad (bool): if True, appropriately pad the input with zero over the edge. If `stride=1`,
            the output will have the same length as the input.
        zeros (float): Number of zero crossings to keep.
            Controls the receptive field of the Finite Impulse Response filter.
            For lowpass filters with low cutoff frequency, e.g. 40Hz at 44.1kHz,
            it is a bad idea to set this to a high value.
            This is likely appropriate for most use. Lower values
            will result in a faster filter, but with a slower attenuation around the
            cutoff frequency.
        fft (bool or None): if True, uses `julius.fftconv` rather than PyTorch convolutions.
            If False, uses PyTorch convolutions. If None, either one will be chosen automatically
            depending on the effective filter size.


    ..warning::
        All the filters will use the same filter size, aligned on the lowest
        frequency provided. If you combine a lot of filters with very diverse frequencies, it might
        be more efficient to split them over multiple modules with similar frequencies.

    ..note::
        A lowpass with a cutoff frequency of 0 is defined as the null function
        by convention here. This allows for a highpass with a cutoff of 0 to
        be equal to identity, as defined in `julius.filters.HighPassFilters`.

    Shape:

        - Input: `[*, T]`
        - Output: `[F, *, T']`, with `T'=T` if `pad` is True and `stride` is 1, and
            `F` is the numer of cutoff frequencies.

    >>> lowpass = LowPassFilters([1/4])
    >>> x = torch.randn(4, 12, 21, 1024)
    >>> list(lowpass(x).shape)
    [1, 4, 12, 21, 1024]
    cutoffsstridepadzerosfftc           
         t         |           t        |      | _        t	        | j                        dk  rt        d      t        | j                        dkD  rt        d      || _        || _        || _	        t        |t	        | j                  D cg c]
  }|dkD  s	| c}      z  dz        | _        || j                  dkD  }|| _        t        j                  d| j                  z  dz   d	      }t        j                  | j                   | j                  dz         }g }	|D ]l  }
|
dk(  rt        j                   |      }n>d|
z  |z  t#        d|
z  t$        j&                  z  |z        z  }||j)                         z  }|	j+                  |       n | j-                  d
t        j.                  |	      d d d f          y c c}w )Nr   z(Minimum cutoff must be larger than zero.g      ?z'A cutoff above 0.5 does not make sense.       r   F)periodicfilters)super__init__listr   min
ValueErrormaxr   r   r   int	half_sizer   torchhann_windowarange
zeros_liker   mathpisumappendregister_bufferstack)selfr   r   r   r   r   cwindowtimer   cutofffilter_	__class__s               H/var/www/stems/demucs_env/lib/python3.12/site-packages/julius/lowpass.pyr   zLowPassFilters.__init__H   s   G}t||q GHHt||s"FGG
UST\\)KQU!)K%LLqPQ;..2%C""1t~~#5#9EJ||T^^OT^^a-?@ 	$F{**40f*v-QZ$''5ID5P0QQ 7;;=(NN7#	$ 	YG(<QW(EF! *Ls   
GGc                 4   t        |j                        }|j                  dd|d         }| j                  r.t	        j                  || j
                  | j
                  fd      }| j                  r#t        || j                  | j                        }n,t	        j                  || j                  | j                        }|j                  dt        | j                               |j                  d   |d<   |j                  ddd      j                  |      S )Nr   	replicate)mode)r   r   r   )r   shapeviewr   Fr   r   r   r   r   conv1dinsertlenr   permutereshape)r)   inputr5   outs       r0   forwardzLowPassFilters.forwarde   s    U[[!

2q%),88EE%$..$..!ATE88UDLLEC((5$,,t{{CCQDLL)*IIbMb	{{1a#++E22    c                     t        |       S Nr	   r)   s    r0   __repr__zLowPassFilters.__repr__r       4  r@   r   T   N)__name__
__module____qualname____doc__r   floatr   boolr   r   r?   rD   __classcell__r/   s   @r0   r   r      sU    3j OS9=G G Gt GG(0G:3!r@   r   c                        e Zd ZdZ	 	 ddededededee   f
 fdZe	d        Z
e	d	        Ze	d
        Ze	d        Ze	d        Zd Zd Z xZS )LowPassFiltera7  
    Same as `LowPassFilters` but applies a single low pass filter.

    Shape:

        - Input: `[*, T]`
        - Output: `[*, T']`, with `T'=T` if `pad` is True and `stride` is 1.

    >>> lowpass = LowPassFilter(1/4, stride=2)
    >>> x = torch.randn(4, 124)
    >>> list(lowpass(x).shape)
    [4, 62]
    r-   r   r   r   r   c                 L    t         |           t        |g||||      | _        y rB   )r   r   r   
_lowpasses)r)   r-   r   r   r   r   r/   s         r0   r   zLowPassFilter.__init__   s$    (&63sKr@   c                 4    | j                   j                  d   S Nr   )rS   r   rC   s    r0   r-   zLowPassFilter.cutoff   s    &&q))r@   c                 .    | j                   j                  S rB   )rS   r   rC   s    r0   r   zLowPassFilter.stride   s    %%%r@   c                 .    | j                   j                  S rB   )rS   r   rC   s    r0   r   zLowPassFilter.pad       """r@   c                 .    | j                   j                  S rB   )rS   r   rC   s    r0   r   zLowPassFilter.zeros   s    $$$r@   c                 .    | j                   j                  S rB   )rS   r   rC   s    r0   r   zLowPassFilter.fft   rX   r@   c                 *    | j                  |      d   S rU   )rS   )r)   r=   s     r0   r?   zLowPassFilter.forward   s    u%a((r@   c                     t        |       S rB   r	   rC   s    r0   rD   zLowPassFilter.__repr__   rE   r@   rF   )rH   rI   rJ   rK   rL   r   rM   r   r   propertyr-   r   r   r   r   r?   rD   rN   rO   s   @r0   rQ   rQ   v   s     DH9=Lu Lc LD LL(0L
 * * & & # # % % # #)!r@   rQ   r=   r   r   r   r   r   c                 J     t        |||||      j                  |       |       S )z[
    Functional version of `LowPassFilters`, refer to this class for more information.
    )r   to)r=   r   r   r   r   r   s         r0   lowpass_filtersr`      s*     F>'63s;>>uEeLLr@   r-   c                 *    t        | |g||||      d   S )z
    Same as `lowpass_filters` but with a single cutoff frequency.
    Output will not have a dimension inserted in the front.
    r   )r`   )r=   r-   r   r   r   r   s         r0   lowpass_filterrb      s      56(FCDQGGr@   rF   )rK   r#   typingr   r   r   torch.nnr   r7   corer   fftconvr   utilsr
   nnModuler   rQ   TensorrL   r   rM   r`   rb    r@   r0   <module>rl      s     %  $   a!UXX__ a!H,!EHHOO ,!` 26<@M5<< M8E? MM*.M M+3D>M 15;?H%,, H HH)-HH*24.Hr@   