o
    2wi                     @   s   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
 d
ejjZG dd dejjZ		ddejdee dedededee fddZ		ddejdededededee fddZdS )z$
FIR windowed sinc lowpass filters.
    N)SequenceOptional)
functional   )sinc)
fft_conv1dsimple_reprc                       sT   e Zd ZdZ		ddee deded	ed
ee f
 fddZ	dd Z
dd Z  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]
    r   T   Ncutoffsstridepadzerosfftc                    s6  t    t|| _t| jdk rtdt| jdkr td|| _|| _|| _	t
|tdd | jD  d | _|d u rC| jdk}|| _tjd| j d	 d
d}t| j | jd	 }g }|D ](}	|	dkrmt|}
nd|	 | td|	 tj |  }
|
|
  }
||
 qa| dt|d d d f  d S )Nr   z(Minimum cutoff must be larger than zero.g      ?z'A cutoff above 0.5 does not make sense.c                 S   s   g | ]}|d kr|qS )r    ).0cr   r   K/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/julius/lowpass.py
<listcomp>S   s    z+LowPassFilters.__init__.<locals>.<listcomp>       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   windowtimer   cutofffilter_	__class__r   r   r   H   s.   

"
""zLowPassFilters.__init__c                 C   s   t |j}|dd|d }| jrtj|| j| jfdd}| jr*t|| j| j	d}n
tj
|| j| j	d}|dt| j |jd |d< |ddd|S )Nr   	replicate)mode)r   r   r   )r   shapeviewr   Fr!   r   r   r   r   conv1dinsertlenr   permutereshape)r,   inputr6   outr   r   r   forwarde   s   
zLowPassFilters.forwardc                 C      t | S Nr   r,   r   r   r   __repr__r      zLowPassFilters.__repr__r   Tr   N)__name__
__module____qualname____doc__r   floatr    boolr   r   r@   rD   __classcell__r   r   r1   r   r
      s    5r
   c                       s   e Zd ZdZ		ddededed	ed
ee f
 fddZe	dd Z
e	dd Ze	dd Ze	dd Ze	dd Zdd Zdd Z  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   Tr   Nr/   r   r   r   r   c                    s"   t    t|g||||| _d S rB   )r   r   r
   
_lowpasses)r,   r/   r   r   r   r   r1   r   r   r      s   
zLowPassFilter.__init__c                 C   s   | j jd S Nr   )rO   r   rC   r   r   r   r/      s   zLowPassFilter.cutoffc                 C      | j jS rB   )rO   r   rC   r   r   r   r         zLowPassFilter.stridec                 C   rQ   rB   )rO   r   rC   r   r   r   r      rR   zLowPassFilter.padc                 C   rQ   rB   )rO   r   rC   r   r   r   r      rR   zLowPassFilter.zerosc                 C   rQ   rB   )rO   r   rC   r   r   r   r      rR   zLowPassFilter.fftc                 C   s   |  |d S rP   )rO   )r,   r>   r   r   r   r@      s   zLowPassFilter.forwardc                 C   rA   rB   r   rC   r   r   r   rD      rE   zLowPassFilter.__repr__rF   )rG   rH   rI   rJ   rK   r    rL   r   r   propertyr/   r   r   r   r   r@   rD   rM   r   r   r1   r   rN   v   s*    




rN   Tr   r>   r   r   r   r   r   c                 C   s   t |||||| | S )z[
    Functional version of `LowPassFilters`, refer to this class for more information.
    )r
   to)r>   r   r   r   r   r   r   r   r   lowpass_filters   s   rU   r/   c                 C   s   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   )rU   )r>   r/   r   r   r   r   r   r   r   lowpass_filter   s   rV   rF   )rJ   r&   typingr   r   r"   torch.nnr   r8   corer   fftconvr   utilsr	   nnModuler
   rN   TensorrK   r    rL   rU   rV   r   r   r   r   <module>   s@   d0

