
    ]i%                         S r SSKrSSKJr  SSKrSSKJr  SSKJ	r	  SSK
Jr   " S S	\R                  R                  5      r  SS
\R                  S\S\S\S\S\\   S\4S jjrS rSS jrSS jrg)a  
Differentiable, Pytorch based resampling.
Implementation of Julius O. Smith algorithm for resampling.
See https://ccrma.stanford.edu/~jos/resample/ for details.
This implementation is specially optimized for when new_sr / old_sr is a fraction
with a small numerator and denominator when removing the gcd (e.g. new_sr = 700, old_sr = 500).

Very similar to [bmcfee/resampy](https://github.com/bmcfee/resampy) except this implementation
is optimized for the case mentioned before, while resampy is slower but more general.

    N)Optional)
functional   )sincsimple_reprc            	          ^  \ rS rSrSrSS\S\S\S\4U 4S jjjrS rSS	\	R                  S
\\   S\4S jjrS rSrU =r$ )ResampleFrac   z7
Resampling from the sample rate `old_sr` to `new_sr`.
old_srnew_srzerosrolloffc                   > [         TU ]  5         [        U[        5      (       a  [        U[        5      (       d  [	        S5      e[
        R                  " X5      nX-  U l        X%-  U l        X0l	        X@l
        U R                  5         g)a	  
Args:
    old_sr (int): sample rate of the input signal x.
    new_sr (int): sample rate of the output.
    zeros (int): number of zero crossing to keep in the sinc filter.
    rolloff (float): use a lowpass filter that is `rolloff * new_sr / 2`,
        to ensure sufficient margin due to the imperfection of the FIR filter used.
        Lowering this value will reduce anti-aliasing, but will reduce some of the
        highest frequencies.

Shape:

    - Input: `[*, T]`
    - Output: `[*, T']` with `T' = int(new_sr * T / old_sr)


.. caution::
    After dividing `old_sr` and `new_sr` by their GCD, both should be small
    for this implementation to be fast.

>>> import torch
>>> resample = ResampleFrac(4, 5)
>>> x = torch.randn(1000)
>>> print(len(resample(x)))
1250
z$old_sr and new_sr should be integersN)super__init__
isinstanceint
ValueErrormathgcdr   r   r   r   _init_kernels)selfr   r   r   r   r   	__class__s         L/mnt/rpi/tmp/demucs-venv-sys/lib/python3.13/site-packages/julius/resample.pyr   ResampleFrac.__init__   sk    6 	&#&&j.E.ECDDhhv&mm
    c                    U R                   U R                  :X  a  g / n[        U R                  U R                   5      nX R                  -  n[        R
                  " U R                  U R                   -  U-  5      U l        [        R                  " U R                  * U R                  U R                   -   5      R                  5       n[        U R                  5       H  nU* U R                  -  X0R                   -  -   U-  nUR                  U R                  * U R                  5      nU[        R                  -  n[        R                  " XPR                  -  S-  5      S-  n[        U5      U-  nUR!                  UR#                  5       5        UR%                  U5        M     U R'                  S[        R(                  " U5      R+                  U R                  SS5      5        g )N   kernelr   )r   r   minr   r   ceilr   _widthtorcharangefloatrangeclamp_picosr   div_sumappendregister_bufferstackview)r   kernelssridxitwindowr    s           r   r   ResampleFrac._init_kernelsC   s_   ;;$++%dkk*
 	ll& ii

T[[ 82 =>
 llDKK<t{{)BCIIKt{{#ADKK#kk/1R7A$**djj1ALAYYq|A~.1F!Wv%FKK

%NN6" $ 	Xu{{7';'@'@aQS'TUr   xoutput_lengthfullc                 j   U R                   U R                  :X  a  U$ UR                  nUR                  S   nUR                  SU5      n[        R
                  " USS2S4   U R                  U R                  U R                   -   4SS9n[        R                  " XR                  U R                   S9nUR                  SS5      R                  [        USS 5      S/-   5      n[        R                  " U R                  U-  U R                   -  5      n[        R                  " U5      R                  5       n	[        R                  " U5      R                  5       n
Uc  U(       a  U	OU
nOAUS:  d  X):  a  [!        S	U	 35      e[        R"                  " U5      nU(       a  [!        S
5      eUSSU24   $ )a  
Resample x.
Args:
    x (Tensor): signal to resample, time should be the last dimension
    output_length (None or int): This can be set to the desired output length
        (last dimension). Allowed values are between 0 and
        ceil(length * new_sr / old_sr). When None (default) is specified, the
        floored output length will be used. In order to select the largest possible
        size, use the `full` argument.
    full (bool): return the longest possible output from the input. This can be useful
        if you chain resampling operations, and want to give the `output_length` only
        for the last one, while passing `full=True` to all the other ones.
r!   N	replicate)mode)strider   r   r   z$output_length must be between 0 and z0You cannot pass both full=True and output_length.)r   r   shapereshapeFpadr$   conv1dr    	transposelistr%   	as_tensorr#   longfloorr   tensor)r   r9   r:   r;   r@   lengthysyfloat_output_lengthmax_output_lengthdefault_output_lengthapplied_output_lengths               r   forwardResampleFrac.forwardr   sp    ;;$++%HIIb&!EE!AtG*t{{DKK$++,EF[YXXaT[[9LLA&&tE#2J'72$'>?#oodkkF.BT[[.PQ!JJ':;@@B %,? @ E E G 9=$5CX!Q-"CCDUCVWXX$)LL$?! !STT,,,,--r   c                     [        U 5      $ )Nr   )r   s    r   __repr__ResampleFrac.__repr__   s    4  r   )r$   r   r   r   r   )   =
ףp=?)NF)__name__
__module____qualname____firstlineno____doc__r   r'   r   r   r%   Tensorr   boolrR   rU   __static_attributes____classcell__)r   s   @r   r
   r
      sd    $s $C $ $5 $ $L-V^#. #.hsm #.RV #.J! !r   r
   r9   r   r   r   r   r:   r;   c                 F    [        XX45      R                  U 5      " XU5      $ )a:  
Functional version of `ResampleFrac`, refer to its documentation for more information.

..warning::
    If you call repeatidly this functions with the same sample rates, then the
    resampling kernel will be recomputed everytime. For best performance, you should use
    and cache an instance of `ResampleFrac`.
)r
   to)r9   r   r   r   r   r:   r;   s          r   resample_fracrd      s$     7::1=aPTUUr   c                     [         R                  " SU -  S-   SS9nUSS S2   n[         R                  " U * S-   U S-
  SU -  5      nU[        R                  -  n[        U5      U-  R                  SSS5      nU$ )N   r   F)periodicr         ?r!   )r%   hann_windowlinspacer   r*   r   r1   )r   winwinoddr6   r    s        r   _kernel_upsample2_downsample2rm      s|     

AIME
:CAYFv|US[!e)<ALA1g$$Q2.FMr   c                 $   U R                   Gt p#[        U5      R                  U 5      n[        R                  " U R                  SSU5      XAS9SSS24   R
                  " / UQUP76 n[        R                  " X/SS9nUR
                  " / UQSP76 $ )a  
Upsample x by a factor of two. The output will be exactly twice as long as the input.
Args:
    x (Tensor): signal to upsample, time should be the last dimension
    zeros (int): number of zero crossing to keep in the sinc filter.

This function is kept only for reference, you should use the more generic `resample_frac`
one. This function does not perform anti-aliasing filtering.
r!   r   padding.N)dim)r@   rm   rc   rB   rD   r1   r%   r0   )r9   r   othertimer    outrM   s          r   
_upsample2ru      s     77LU*5144Q7F
((166"a&
>sABw
G
L
L
Ze
ZUY
ZCQH"%A665"r   c                    U R                   S   S-  S:w  a  [        R                  " U S5      n U SSSS24   nU SSSS24   nUR                   Gt pE[        U5      R	                  U 5      nU[        R
                  " UR                  SSU5      XaS9SSS24   R                  " / UQUP76 -   nUR                  " / UQSP76 R                  S	5      $ )
a}  
Downsample x by a factor of two. The output length is half of the input, ceiled.
Args:
    x (Tensor): signal to downsample, time should be the last dimension
    zeros (int): number of zero crossing to keep in the sinc filter.

This function is kept only for reference, you should use the more generic `resample_frac`
one. This function does not perform anti-aliasing filtering.
r!   r   r   )r   r   .Nr   ro   rh   )r@   rB   rC   rm   rc   rD   r1   mul)r9   r   xevenxoddrr   rs   r    rt   s           r   _downsample2rz      s     	wwr{Q!EE!Vc3Q3hKES!$Q$Y<D::LU*5144Q7F
!((499RD16I#sPRs(SXX 	 C88UB##C((r   )rW   rX   NF)rW   )r]   r   typingr   r%   torch.nnr   rB   corer   utilsr   nnModuler
   r^   r   r'   r_   rd   rm   ru   rz    r   r   <module>r      s   
    $  !588?? !F 5:DIVU\\ V3 V VV,1V!)#V=AV"")r   