
    ]i)                        S SK JrJr  S SKrS SKrS SKrS SKrS SKrS SK	J
r
  S SKJr  S SKrS SKrS SKrS SKJr  S\S\S\S	\R&                  4S
 jrS\S\S\S\4S jr " S S\5      r " S S\5      rS!S jr        S"S\S\\   S\S\S\\   S\\\R<                  4   S\S\4S jjr  S#S\R@                  S\\   S\\   S	\R@                  4S  jjr!g)$    )OptionalUnionN)Path)redirect_stderr)modelraten_fft	bandwidthreturnc                     [         R                  " SU S-  US-  S-   SS9n[         R                  " [         R                  " X2:*  5      S   5      S-   $ )zConvert bandwidth to maximum bin count

Assuming lapped transforms such as STFT

Args:
    rate (int): Sample rate
    n_fft (int): FFT length
    bandwidth (float): Target bandwidth in Hz

Returns:
    np.ndarray: maximum frequency bin
r         T)endpoint)nplinspacemaxwhere)r   r	   r
   freqss       L/mnt/rpi/tmp/demucs-venv-sys/lib/python3.13/site-packages/openunmix/utils.pybandwidth_to_max_binr      sI     KK4!8UaZ!^dCE66"((5-.q12Q66    stateis_bestpathtargetc                     [         R                  " U [        R                  R	                  X#S-   5      5        U(       a;  [         R                  " U S   [        R                  R	                  X#S-   5      5        gg)a  Convert bandwidth to maximum bin count

Assuming lapped transforms such as STFT

Args:
    state (dict): torch model state dict
    is_best (bool): if current model is about to be saved as best model
    path (str): model path
    target (str): target name
z.chkpnt
state_dictz.pthN)torchsaveosr   join)r   r   r   r   s       r   save_checkpointr"   #   sP     
JJubggll4));<=

5&TF?(KL r   c                   .    \ rS rSrSrS rS rSS jrSrg)	AverageMeter5   z1Computes and stores the average and current valuec                 $    U R                  5         g N)resetselfs    r   __init__AverageMeter.__init__8   s    

r   c                 <    SU l         SU l        SU l        SU l        g )Nr   )valavgsumcountr)   s    r   r(   AverageMeter.reset;   s    
r   c                     Xl         U =R                  X-  -  sl        U =R                  U-  sl        U R                  U R                  -  U l        g r'   )r.   r0   r1   r/   )r*   r.   ns      r   updateAverageMeter.updateA   s8    CG

a
88djj(r   )r/   r1   r0   r.   N)r   )	__name__
__module____qualname____firstlineno____doc__r+   r(   r5   __static_attributes__ r   r   r$   r$   5   s    ;)r   r$   c                   .    \ rS rSrSrSS jrS rS rSrg)	EarlyStoppingH   zEarly Stopping Monitorc                     Xl         X l        X0l        S U l        SU l        S U l        U R                  X5        US:X  a	  S U l        g g )Nr   c                     g)NTr=   )abs     r   <lambda>(EarlyStopping.__init__.<locals>.<lambda>U   s    $r   )mode	min_deltapatiencebestnum_bad_epochs	is_better_init_is_better)r*   rG   rH   rI   s       r   r+   EarlyStopping.__init__K   sH    	" 	T-q=.DN r   c                     U R                   c  Xl         g[        R                  " U5      (       a  gU R                  XR                   5      (       a  SU l        Xl         OU =R                  S-  sl        U R                  U R
                  :  a  gg)NFTr   r   )rJ   r   isnanrL   rK   rI   )r*   metricss     r   stepEarlyStopping.stepW   so    99I88G>>'99--"#DI1$$--/r   c                 z   ^ US;  a  [        SU-   S-   5      eUS:X  a  U4S jU l        US:X  a  U4S jU l        g g )N>   r   minzmode z is unknown!rU   c                    > XT-
  :  $ r'   r=   rC   rJ   rH   s     r   rE   /EarlyStopping._init_is_better.<locals>.<lambda>n       Q	1A-Ar   r   c                    > XT-   :  $ r'   r=   rW   s     r   rE   rX   p   rY   r   )
ValueErrorrL   )r*   rG   rH   s     `r   rM   EarlyStopping._init_is_betterj   s@    ~%Wt^n<==5=ADN5=ADN r   )rJ   rL   rH   rG   rK   rI   N)rU   r   
   )	r7   r8   r9   r:   r;   r+   rR   rM   r<   r=   r   r   r?   r?   H   s     
/&Br   r?   c                    [        U [        5      (       a  U /n [        U5      R                  5       nUR	                  5       (       dE   [        [        US-   5      n[        R                  " 5       n[        U5         U" XUS9sSSS5        $ 0 nU  H  n[        [        XHS-   5      S5       n	[        R                   " U	5      n
SSS5        [#        [        U5      R%                  SU-  5      5      n[&        R                   " XS9n[(        R*                  " W
S	   S
   S-  S-   U
S	   S   U
S	   S   US   R,                  S   S9Xx'   U(       a  Xx   R/                  USS9  Xx   R1                  U5        M     U$ ! , (       d  f       O= f[        UR                  5       5        g! [         a    [        S5      ef = f! , (       d  f       N= f)zCore model loader

target model path can be either <target>.pth, or <target>-sha256.pth
(as used on torchub)

The loader either loads the models from a known model string
as registered in the __init__.py or loads from custom configs.
_spec)targetsdevice
pretrainedNz Model does not exist on torchhubz.jsonrz%s*.pth)map_locationargsnfftr   r   nb_channelshidden_size
input_meanr   )nb_binsrg   rh   max_binF)strict)
isinstancestrr   
expanduserexistsgetattr	openunmixioStringIOr   printgetvalueAttributeError	NameErroropenjsonloadnextglobr   r   	OpenUnmixshapeload_state_dictto)r`   model_str_or_pathra   rb   
model_path
hub_loadererrmodelsr   streamresultstarget_model_pathr   s                r   load_target_modelsr   s   s    '3)'(335J	@ ,=,GHJ++-C %!'ZX &% Fd:'78#>&))F+ ? !%T*%5%:%:9v;M%N OJJ0FE"__/14q8#FOM:#FOM:l+11!4	FN ..uU.CNf%% & 7 &%#,,.! 	@>??	@ ?>s0   3F" ;E7	F" +F;7
F F" "F8;
G		r   r`   niterresidualwiener_win_lenra   rb   
filterbankc                    [        U 5      R                  5       nUR                  5       (       a  Uc  [        S5      e[	        XUS9n	[        [        US5      S5       n
[        R                  " U
5      nSSS5        [        R                  " U	UUUWS   US   US   US	   US
9	R                  U5      nU$ [        [        U 5      nU" UUSUUUUS9nU$ ! , (       d  f       Ne= f)a  Separator loader

Args:
    model_str_or_path (str): Model name or path to model _parent_ directory
        E.g. The following files are assumed to present when
        loading `model_str_or_path='mymodel', targets=['vocals']`
        'mymodel/separator.json', mymodel/vocals.pth', 'mymodel/vocals.json'.
        Defaults to `umxl`.
    targets (list of str or None): list of target names. When loading a
        pre-trained model, all `targets` can be None as all targets
        will be loaded
    niter (int): Number of EM steps for refining initial estimates
        in a post-processing stage. `--niter 0` skips this step altogether
        (and thus makes separation significantly faster) More iterations
        can get better interference reduction at the price of artifacts.
        Defaults to `1`.
    residual (bool): Computes a residual target, for custom separation
        scenarios when not all targets are available (at the expense
        of slightly less performance). E.g vocal/accompaniment
        Defaults to `False`.
    wiener_win_len (int): The size of the excerpts (number of frames) on
        which to apply filtering independently. This means assuming
        time varying stereo models and localization of sources.
        None means not batching but using the whole signal. It comes at the
        price of a much larger memory usage.
        Defaults to `300`
    device (str): torch device, defaults to `cpu`
    pretrained (bool): determines if loading pre-trained weights
    filterbank (str): filterbank implementation method.
        Supported are `['torch', 'asteroid']`. `torch` is about 30% faster
        compared to `asteroid` on large FFT sizes such as 4096. However,
        asteroids stft can be exported to onnx, which makes is practical
        for deployment.
Nz-For custom models, please specify the targets)r`   r   rb   zseparator.jsonrc   sample_raterf   nhoprg   )	target_modelsr   r   r   r   r	   n_hoprg   r   T)r`   ra   rb   r   r   r   r   )r   ro   rp   UserWarningr   ry   rz   r{   r   	Separatorr   rq   rr   )r   r`   r   r   r   ra   rb   r   r   r   r   enc_conf	separatorr   s                 r   load_separatorr      s   X '(335J ?MNN*7eop$z#34c:fyy(H ; OO') /6"6" /!

 "V* 	2  Y(9:
)!
	 9 ;:s   C
C!audio
model_ratec                    [         R                  " U R                  U R                  S9n[	        U5      S:X  a  U S   n O3[	        U5      S:X  a$  UR                  5       S::  a  U S   n O
U SS2SS4   n U R                  S   U R                  S   :  a  U R                  SS5      n U R                  S   S:  a  [        R                  " S5        U SSS24   n U R                  S   S:X  a  [         R                  " U SSS	9n X:w  aU  [        R                  " S
5        [        R                  R                  XSS9R                  U R                  5      nU" U 5      n U $ )a  
From an input tensor, convert it to a tensor of shape
shape=(nb_samples, nb_channels, nb_timesteps). This includes:
-  if input is 1D, adding the samples and channels dimensions.
-  if input is 2D
    o and the smallest dimension is 1 or 2, adding the samples one.
    o and all dimensions are > 2, assuming the smallest is the samples
      one, and adding the channel one
- at the end, if the number of channels is greater than the number
  of time steps, swap those two.
- resampling to target rate if necessary

Args:
    audio (Tensor): input waveform
    rate (float): sample rate for the audio
    model_rate (float): sample rate for the model

Returns:
    Tensor: [shape=(nb_samples, nb_channels=2, nb_timesteps)]
)ra   r   )NN.r   )N.N.zBChannel count > 2!. Only the first two channels will be processed!)dimzresample to model sample ratesinc_interpolation)	orig_freqnew_freqresampling_method)r   	as_tensorr   ra   lenrU   	transposewarningswarnrepeat_interleave
torchaudio
transformsResampler   )r   r   r   r   	resamplers        r   
preprocessr      s8   2 OOEKK=E
5zQo&	Uq99;!)$E !T3,'E{{1~A&1%{{1~]^c2A2g{{1~''qa856 ))22CW 3 

"U\\
 	 % Lr   )umxlcpuT)r   Nr   Fi,  r   Tr   )NN)"typingr   r   r   r    numpyr   r   r   pathlibr   
contextlibr   rs   rz   rr   r   floatintndarrayr   dictboolrn   r"   objectr$   r?   r   listra   r   Tensorr   r=   r   r   <module>r      sa   "  	     & 	   7u 7S 7U 7rzz 7$M4 M$ Mc M3 M$)6 )&(BF (BV.d $"$'',QQd^Q Q 	Q
 SMQ #u||#$Q Q Ql !"&8<<8
5/8 8 \\	8r   