
    i                    V    d Z ddlmZ ddlZddlmZ ddlmZ  G d d      Z	d	 Z
dd
Zy)zPublic MLX API (Demucs-style).    )annotationsN)Path   )MLX_MODEL_REGISTRYc                      e Zd Z	 	 	 	 	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZedd       Zedd       Zed        Zddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd	 Z	d
 Z
dd	 	 	 ddZdd	 	 	 	 	 ddZy)	SeparatorNFc                   |t         vr=dj                  t        t        j                                     }t	        d| d|       |t        d      |dvrt	        d      |t        d      t        |      dk  rt	        d	      d
t        |      cxk  rdk  st	        d       t	        d      |t        |      dk  rt	        d      t        |
      dk  rt	        d      |	 t        |      }|| _	        t        |      | _
        t        |      | _        || _        |t        |      nd | _        || _        t        |
      | _        || _        |	| _        || _        || _        ddlm}  ||      | _        t/        | j,                  d      r| j,                  j1                          y y # t        t        f$ r}t	        d      |d }~ww xY w)Nz, zUnknown model 'z'. Available: z+Custom repos are not supported in MLX mode.)r   r   z0MLX backend does not support multi-process jobs.z(Callbacks are not supported in MLX mode.r   shifts must be >= 0.              ?overlap must be in [0, 1)."segment must be > 0 when provided.zbatch_size must be > 0. seed must be an integer or None.r   )get_mlx_modeleval)r   joinsortedkeys
ValueErrorNotImplementedErrorintfloat	TypeError
model_nameshiftsoverlapsplitsegmentseed
batch_sizejobsprogresscallbackcallback_argmodel_converterr   _modelhasattrr   )selfmodelrepor   r   r   r   r   r!   r"   r    r#   r$   knownexcr   s                   c/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/demucs_mlx/api.py__init__zSeparator.__init__   s    **IIf%7%<%<%>?@Eug^E7KLL%&STTvOPP%&PQQv;?344uW~++9:: ,9::5>Q#6ABBz?a677N4y  &kW~
)0)<uW~$	j/	  (2#E*4;;'KK (! z* N !CD#MNs   *F/ /G>G

Gc                @    t        | j                  j                        S N)r   r&   
samplerater(   s    r-   r1   zSeparator.samplerateA   s    4;;))**    c                @    t        | j                  j                        S r0   )r   r&   audio_channelsr2   s    r-   r5   zSeparator.audio_channelsE   s    4;;--..r3   c                    | j                   S r0   )r&   r2   s    r-   r)   zSeparator.modelI   s    {{r3   )r   r   r   r   r   r"   c                  |)t        |      dk  rt        d      t        |      | _        |4t        |      }d|cxk  rdk  st        d       t        d      || _        ||| _        |"t        |      }|dk  rt        d      || _        |	 t        |      | _        ||| _	        y y # t        t        f$ r}	t        d      |	d }	~	ww xY w)Nr   r
   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r"   )
r(   r   r   r   r   r   r"   	overlap_fseg_fr,   s
             r-   update_parameterzSeparator.update_parameterM   s     6{Q !788f+DKgI9*s* !=>> + !=>>$DLDJ'NEz !EFF DLNI	 $DM   z* N !CD#MNs   B- -C<CCc                   dd l }|j                  |      }|j                  dk7  rt        d      |j                  d   | j
                  k7  r| j
                  dk(  r|j                  dd      }|S |j                  d   dk(  r/| j
                  dkD  r |j                  || j
                  df      }|S |j                  d   | j
                  kD  r|d | j
                  d d f   }|S t        d|j                  d    d| j
                   d	      |S 
Nr      z)Expected wav with shape (channels, time).r   T)axiskeepdimsz
Audio has z channels but model expects .)numpyasarrayndimr   shaper5   meantile)r(   wavnpwav_nps       r-   _prepare_wavzSeparator._prepare_wavo   s   C;;!HII<<?d111""a'!d;  aA%$*=*=*A$*=*=q)AB  a4#6#66 4!4!4 4a 78
  ! a 11MdNaNaMbbcd  r3   c                v   dd l m} |j                  dk7  rt        d      t	        |j
                  d         | j                  k7  r| j                  dk(  r|j                  |dd      }|S t	        |j
                  d         dk(  rE| j                  dkD  r6|j                  || j                  t	        |j
                  d         f      }|S t	        |j
                  d         | j                  kD  r|d | j                  d d f   }|S t        dt	        |j
                  d          d| j                   d	      |S r<   )	mlx.corecorerC   r   r   rD   r5   rE   broadcast_to)r(   rG   mxs      r-   _prepare_wav_mxzSeparator._prepare_wav_mx   s6   88q=HIIsyy| 3 33""a'ggcDg9 
 SYYq\"a'D,?,?!,CoocD,?,?SYYq\AR+ST 
 SYYq\"T%8%88.4...12 
	 ! SYYq\!2 3 4))-)<)<(=Q@  
r3   	return_mxc                  dd l m} dd l}ddlm} t        ||j                        r| j                  |      }|d   }n'| j                  |      }|j                  |      }|d   } || j                  || j                  | j                  | j                  | j                  | j                  | j                  | j                   	      }	|j#                  |	       |	d   }
|r9t%        | j                  j&                        D ci c]  \  }}||
|    }}}||fS |j)                  |      }|j)                  |
      }t%        | j                  j&                        D ci c]  \  }}|||    }}}||fS c c}}w c c}}w )Nr   r   )apply_model)N.)r   r   r   r   r"   r    r   )rL   rM   rA   	apply_mlxrT   
isinstancearrayrP   rJ   r&   r   r   r   r   r"   r    r   r   	enumeratesourcesrB   )r(   rG   rR   rO   rH   rT   wav_mxmixrI   	estimatesstems_mxidxnamestemsstems_nps                  r-   separate_tensorzSeparator.separate_tensor   s\    	*c288$))#.F#C&&s+FXXf%F#CKK;;**LLLL]]

	 		Q<:CDKKDWDW:XY:XYS$T8C=(:XEY5= F#::h'6?@S@S6TU6Tdx}$6TUu} Z Vs    E2E8c                   dd l m} dd l}|j                  t	        |      | j
                  d      \  }}|j                  |d      }| j                  ||      S )Nr   float32)srdtype)r   r   rQ   )rL   rM   mlx_audio_ioloadstrr1   	transposerb   )r(   pathrR   rO   macaudio_mxre   rG   s           r-   separate_audio_filezSeparator.separate_audio_file   sP     	"xxD	dooYxO"ll8V,##C9#==r3   )htdemucsNr   g      ?TNNr   F   NN)r)   ri   r*   ztp.Optional[Path]r   r   r   r   r   boolr   tp.Optional[float]r   tp.Optional[int]r!   r   r"   rq   r    r   r#   z&tp.Optional[tp.Callable[[dict], None]]r$   ztp.Optional[dict])returnr   )r   rs   r   rr   r   tp.Optional[bool]r   rr   r   rs   r"   ru   rt   None)rR   rq   rt   &tp.Tuple[tp.Any, tp.Dict[str, tp.Any]])rk   ztp.Union[str, Path]rR   rq   rt   rw   )__name__
__module____qualname__r.   propertyr1   r5   r)   r:   rJ   rP   rb   rn    r3   r-   r   r   
   s     "&&*!%;?*.44  4 	4
 4 4 $4 4 4 4 4 94 (4l + + / /   $(&*#'&*!%&* % ! % $	 %
 ! % $ %  % $ % 
 %D&.  	% 	%
 
0%V  	>!> 	>
 
0>r3   r   c                     ddl m}  || i |S )Nr   )
save_audio)audior~   )argskwargs_save_audios      r-   r~   r~      s    0'''r3   c                     t        j                         D  cg c]  \  } }|j                  d      r|  c}} t        j                         D  cg c]  \  } }|j                  d      s|  c}} dS c c}} w c c}} w )Nis_bag)singlebag)r   itemsget)kvs     r-   list_modelsr      sh    !3!9!9!;S!;A155?1!;S0668L8daAEE(O8L SLs   A4A4A:*A:)rt   ztp.Dict[str, tp.List[str]])__doc__
__future__r   typingtppathlibr   mlx_registryr   r   r~   r   r|   r3   r-   <module>r      s+    $ "   ,}> }>@(
r3   