o
    pi                     @   s   d 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
 G dd	 d	ejjZ		
	ddejdedee deee  dededee fddZdS )zH
Decomposition of a signal over frequency bands in the waveform domain.
    )OptionalSequenceN   )mel_frequencies)LowPassFilters)simple_reprc                       sn   e Zd ZdZ			ddedee deee  ded	ed
ee f fddZ	dd Z
edd Zdd Z  ZS )
SplitBandsa  
    Decomposes a signal over the given frequency bands in the waveform domain using
    a cascade of low pass filters as implemented by `julius.lowpass.LowPassFilters`.
    You can either specify explicitely the frequency cutoffs, or just the number of bands,
    in which case the frequency cutoffs will be spread out evenly in mel scale.

    Args:
        sample_rate (float): Sample rate of the input signal in Hz.
        n_bands (int or None): number of bands, when not giving them explictely with `cutoffs`.
            In that case, the cutoff frequencies will be evenly spaced in mel-space.
        cutoffs (list[float] or None): list of frequency cutoffs in Hz.
        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. See `LowPassFilters` for more informations.
        fft (bool or None): See `LowPassFilters` for more info.

    ..note::
        The sum of all the bands will always be the input signal.

    ..warning::
        Unlike `julius.lowpass.LowPassFilters`, the cutoffs frequencies must be provided in Hz along
        with the sample rate.

    Shape:

        - Input: `[*, T]`
        - Output: `[B, *, T']`, with `T'=T` if `pad` is True.
            If `n_bands` was provided, `B = n_bands` otherwise `B = len(cutoffs) + 1`

    >>> bands = SplitBands(sample_rate=128, n_bands=10)
    >>> x = torch.randn(6, 4, 1024)
    >>> list(bands(x).shape)
    [10, 6, 4, 1024]
    NT   sample_raten_bandscutoffspadzerosfftc                    s   t    |d u |d u  dkrtd | _|| _|d ur!t|nd | _|| _|| _|| _	|d u rT|d u r9td|dksEtd| dt
|d d d dd }nt|d	  kr`td
t|dkrxt fdd|D |||d| _d S d | _d S )Nr   z;You must provide either n_bands, or cutoffs, but not boths.z+You must provide one of n_bands or cutoffs.z&n_bands must be greater than one (got )r      g      ?z1A cutoff above sample_rate/2 does not make sense.c                    s   g | ]}|  qS  r   .0cr
   r   @/home/ubuntu/.local/lib/python3.10/site-packages/julius/bands.py
<listcomp>K   s    z'SplitBands.__init__.<locals>.<listcomp>)r   r   r   )super__init__
ValueErrorr
   r   list_cutoffsr   r   r   r   maxlenr   lowpass)selfr
   r   r   r   r   r   	__class__r   r   r   2   s,   

zSplitBands.__init__c                 C   sj   | j d u r	|d  S |  |}|d }|g}|dd  D ]}|| }|| |}q|||  t|S )Nr   r   )r!   appendtorchstack)r"   inputlowslowbandslow_and_bandbandr   r   r   forwardQ   s   



zSplitBands.forwardc                    s4    j d ur j S  jd ur fdd jjD S g S )Nc                    s   g | ]}| j  qS r   r   r   r"   r   r   r   e   s    z&SplitBands.cutoffs.<locals>.<listcomp>)r   r!   r   r/   r   r/   r   r   `   s
   

zSplitBands.cutoffsc                 C   s   t | d| jidS )Nr   )	overrides)r   r   r/   r   r   r   __repr__i   s   zSplitBands.__repr__NNTr	   N)__name__
__module____qualname____doc__floatr   intr   boolr   r.   propertyr   r1   __classcell__r   r   r#   r   r      s$    #

r   Tr	   signalr
   r   r   r   r   r   c                 C   s   t ||||||| | S )z
    Functional version of `SplitBands`, refer to this class for more information.

    >>> x = torch.randn(6, 4, 1024)
    >>> list(split_bands(x, sample_rate=64, cutoffs=[12, 24]).shape)
    [3, 6, 4, 1024]
    )r   to)r<   r
   r   r   r   r   r   r   r   r   split_bandsm   s   
r>   r2   )r6   typingr   r   r&   corer   r!   r   utilsr   nnModuler   Tensorr7   r8   r9   r>   r   r   r   r   <module>   s&   _
