ó
    â“,jŒ%  ã                   óè   • 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         €Ú�C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\julius/resample.pyr   ÚResampleFrac.__init__   sk   ø€ ô6 	‰ÑÔÜ˜&¤#×&Ñ&¬j¸Ä×.EÑ.EÜÐCÓDÐDÜ�hŠh�vÓ&ˆØ‘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_  € Ø�;‰;˜$Ÿ+™+Ó%ØàˆÜ�—‘˜dŸk™kÓ*ˆð
 	�l‰lÑˆô& —i’i §
¡
¨T¯[©[Ñ 8¸2Ñ =Ó>ˆŒô
 �lŠl˜DŸK™K˜<¨¯©°t·{±{Ñ)BÓC×IÑIÓKˆÜ�t—{‘{Ö#ˆAØ��D—K‘K‘ #§k¡k¡/Ñ1°RÑ7ˆAØ—‘˜$Ÿ*™*˜ d§j¡jÓ1ˆAØ”—‘‰LˆAÜ—Y’Y˜q§¡™|¨A™~Ó.°Ñ1ˆFÜ˜!“W˜vÑ%ˆFà�K‰K˜Ÿ
™
›Ô%Ø�N‰N˜6Ö"ñ $ð 	×Ñ˜X¤u§{¢{°7Ó';×'@Ñ'@ÀÇÁÈaÐQSÓ'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Ø—‘ˆØ—‘˜‘ˆØ�I‰I�b˜&Ó!ˆÜ�EŠE�!’A�t�G‘*˜tŸ{™{¨D¯K©K¸$¿+¹+Ñ,EÐFÈ[ÑYˆÜ�XŠX�aŸ™¨T¯[©[Ñ9ˆØ�L‰L˜˜AÓ×&Ñ&¤t¨E°#°2¨JÓ'7¸2¸$Ñ'>Ó?ˆä#Ÿošo¨d¯k©k¸FÑ.BÀTÇ[Á[Ñ.PÓQÐÜ!ŸJšJÐ':Ó;×@Ñ@ÓBÐÜ %§¢Ð,?Ó @× EÑ EÓ GÐàÑ Þ9=Ñ$5ÐCXÑ!Ø˜QÓ -Ó"CÜÐCÐDUÐCVÐWÓXÐXä$)§L¢L°Ó$?Ð!ÞÜ Ð!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ñ^#.˜Ÿ™ð #.°h¸s±mð #.Ð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Ô=¸aÐPTÓ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¨™M°EÑ
:€CØ���A�‰Y€FÜ�Š˜�v ‘| U¨S¡[°!°e±)Ó<€AØŒ�‰�L€AÜ�1‹g˜Ñ×$Ñ$ 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‰   € ð —7‘7�L€UÜ*¨5Ó1×4Ñ4°QÓ7€FÜ
�(Š(�1—6‘6˜"˜a Ó&¨Ñ
>¸sÀAÁB¸wÑ
G×
LÒ
LÐ
ZÈeÐ
ZÐUYÒ
Z€CÜ�Š�Q�H "Ñ%€AØ�6Š6Ð�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Û   € ð 	‡w�wˆr�{�Q�˜!ÓÜ�EŠE�!�VÓˆØˆc‘3�Q�3ˆh‰K€EØˆS�!�$�Q�$ˆY‰<€DØ—:‘:�L€UÜ*¨5Ó1×4Ñ4°QÓ7€FØ
”!—(’(˜4Ÿ9™9 R¨¨DÓ1°6ÑIÈ#ÈsÐPRÈsÈ(ÑS×XÒXð Ø	ðØòñ €Cà�8Š8Ð�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–   ðñ
ó Ý ã Ý $å Ý ô!�5—8‘8—?‘?ô !ðF 5:ØDIñV�U—\‘\ð V¨3ð V¸ð VØðVØ,1ðVà!)¨#¡ðVà=AõVò"ôõ")r   