+
    TV-jØi  ã                   ó  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHtHtHtHtHtHtHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHtHtH t H!t!H"t"H#t# ]! R4      t$R R lt%. R0Ot&R	 R
 lt'R1R R llt(R R lt)R R lt*R2R R llt+R R lt,R3R R llt-Rs.Rs/Rs0Rs1Rs2R t3R t4R t5R t6R t7R4R R llt8R R lt9R5R  R! llt:R6R" R# llt;R7R$ R% llt<. R8Ot=R& R' lt>R( R) lt?R* R+ lt@R, R- ltAR. R/ ltBR# )9z®Utility functions for mlx_audio.

This module provides a unified interface for loading TTS, STT, and STS models,
with lazy imports to avoid loading unnecessary dependencies.
N)ÚPath)ÚListÚOptionalÚTupleÚTypeÚTypeVarÚUnionÚ
get_originÚget_type_hints)Úsnapshot_download)ÚSTR_TO_WINDOW_FNÚbartlettÚblackmanÚhammingÚhanningÚistftÚmel_filtersÚstftÚTc                óR   € V ^8„  d   QhR\         \        ,          R\        R\        /# )é   Ú
data_classÚdataÚreturn)r   r   Údict)Úformats   "Ú`/Volumes/fast/ai/experiments/ui-tars-smoke/.venv/lib/python3.14/site-packages/mlx_audio/utils.pyÚ__annotate__r   -   s%   € ÷  ñ  œ$œq�'ð  ¬ð  ´!ñ  ó    c                 ó0  € \         P                  ! V 4      '       g   \        V  R 24      h\        V 4      p/ p\         P                  ! V 4       F¹  pVP
                  pWQ9  d   K  W,          pW%,          p\        V4      pV\        J d=   VP                   U	u. uF  q™\        R4      Jg   K  V	NK  	  p
p	V
'       d
   V
^ ,          p\         P                  ! V4      '       d"   \        V\        4      '       d   \        Wv4      pWcV&   K»  	  V ! R/ VB # u up	i )z is not a dataclassN© )ÚdataclassesÚis_dataclassÚ	TypeErrorr
   ÚfieldsÚnamer	   r   Ú__args__ÚtypeÚ
isinstancer   Ú	from_dict)r   r   Úfield_typesÚkwargsÚfieldÚ
field_nameÚvalueÚ
field_typeÚoriginÚaÚargss   &&         r   r)   r)   -   sù   € ä×#Ò# J×/Ò/Ü˜:˜,Ð&9Ð:Ó;Ð;ä  Ó,€KØ€Fä×#Ò# JÖ/ˆØ—Z‘Zˆ
ØÔ!ÙàÕ ˆØ Õ,ˆ
ô ˜JÓ'ˆØ”U‹?à)×2Ò2ÓJÑ2˜!¼tÀD»zÐ6I—A�AÑ2ˆDÐJßØ! !�W�
ô ×#Ò# J×/Ò/´J¸uÄd×4KÒ4KÜ˜jÓ0ˆEà"ˆzÓñ) 0ñ, Ñ˜ÑÐùò Ks   ÂDÂ-Dc                ó0   € V ^8„  d   QhR\         R\        /# )r   Úpathr   ©ÚstrÚbool)r   s   "r   r   r   b   s   € ÷ ñ œð ¤ñ r   c                óÜ   € V P                  R4      ;'       gU    V P                  R4      ;'       g<    V P                  R4      ;'       g#    \        V 4      ^8„  ;'       d    V ^,          R8H  # )z5Check if the path looks like a local filesystem path.Ú.Ú/Ú~Ú:)Ú
startswithÚlen)r4   s   &r   Ú_is_local_pathr?   b   sh   € ð 	�‰˜Ó÷ 	.ð 	.Ø�?‰?˜3Ó÷	.ð 	.à�?‰?˜3Ó÷	.ð 	.ô �‹I˜‰M×,Ð,˜d 1�g¨™nð	r   c          
      ó–   € V ^8„  d   QhR\         R\        \         ,          R\        R\        \        \         ,          ,          R\        /# )r   Úpath_or_hf_repoÚrevisionÚforce_downloadÚallow_patternsr   )r6   r   r7   r   r   )r   s   "r   r   r   l   sG   € ÷ ,ñ ,Üð,ä”s�mð,ô ð,ô œT¤#�YÕ'ð	,ô
 
ñ,r   c           	     óê   € \        V 4      P                  4       pVP                  4       '       d   V# \        V 4      '       d   \	        RV  24      hVf   \
        p\        \        V VVVR7      4      pV# )a   
Ensures the model is available locally. If the path does not exist locally,
it is downloaded from the Hugging Face Hub.

Args:
    path_or_hf_repo: The local path or Hugging Face repository ID of the model.
    revision: A revision id which can be a branch name, a tag, or a commit hash.
    force_download: Force re-download even if cached.
    allow_patterns: File patterns to download. Defaults to common model files.

Returns:
    Path: The path to the model.

Raises:
    FileNotFoundError: If a local path is provided but doesn't exist.
zLocal path not found: )rB   rD   rC   )r   Ú
expanduserÚexistsr?   ÚFileNotFoundErrorÚDEFAULT_ALLOW_PATTERNSr   )rA   rB   rC   rD   Ú
model_paths   &&&& r   Úget_model_pathrK   l   s€   € ô, �oÓ&×1Ñ1Ó3€Jà×Ñ×ÒØÐô �o×&Ò&ÜÐ"8¸Ð8IÐ JÓKÐKð ÒÜ/ˆäÜØØØ)Ø)ô		
ó€Jð Ðr   c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# ©r   rJ   r   )r   r6   r   r   )r   s   "r   r   r   ›   s'   € ÷ Añ AœE¤#¤t )Õ,ð A¼4ñ Ar   c                ó2  € \        V \        4      '       d   \        V 3/ VB p V R,          pVP                  4       '       d7   \	        VRR7      ;_uu_ 4       p\
        P                  ! V4      uuRRR4       # \        RV  24      h  + '       g   i     L; i)a?  Load model configuration from a path or Hugging Face repo.

Args:
    model_path: Local path or Hugging Face repo ID to load config from
    **kwargs: Additional keyword arguments (revision, force_download)

Returns:
    dict: Model configuration

Raises:
    FileNotFoundError: If config.json is not found at the path
zconfig.jsonzutf-8)ÚencodingNzConfig not found at )r(   r6   rK   rG   ÚopenÚjsonÚloadrH   )rJ   r+   Úconfig_fileÚfs   &,  r   Úload_configrU   ›   sy   € ô �*œc×"Ò"Ü# JÑ9°&Ñ9ˆ
à˜}Õ,€KØ×Ñ×ÒÜ�+¨×0Õ0°AÜ—9’9˜Q“<÷ 1Ò0ô Ð2°:°,Ð?Ó
@Ð@÷ 1×0ús   ÁBÂB	c                ó0   € V ^8„  d   QhR\         R\        /# rM   )r   r   )r   s   "r   r   r   ³   s   € ÷ ñ œTð ¤dñ r   c                ó:  € \         P                   ! \        V R,          4      4      pV'       g'   \         P                   ! \        V R,          4      4      pV'       g   \        RV  24      h/ pV F(  pVP                  \        P
                  ! V4      4       K*  	  V# )zÕLoad model weights from safetensors or npz files.

Args:
    model_path: Path to the model directory

Returns:
    dict: Dictionary of weight name -> array

Raises:
    FileNotFoundError: If no weight files found
ú*.safetensorsú*.npzz.No weight files (safetensors or npz) found in )Úglobr6   rH   ÚupdateÚmxrR   )rJ   Úweight_filesÚweightsÚwfs   &   r   Úload_weightsr`   ³   s}   € ô —9’9œS ¨oÕ!=Ó>Ó?€LçÜ—y’y¤ Z°'Õ%9Ó!:Ó;ˆçÜØ<¸Z¸LÐIó
ð 	
ð €GÛˆØ�‰”r—w’w˜r“{Ö#ñ ð €Nr   c          
      óv   € V ^8„  d   QhR\         P                  R\        R\        R\        \        ,          RR/# )r   ÚmodelÚconfigr^   Úmodel_quant_predicater   N)ÚnnÚModuler   r   Úcallable)r   s   "r   r   r   Ñ   sC   € ÷ /ñ /Ü�9‰9ð/äð/ô ð/ô $¤HÕ-ð	/ð
 
ñ/r   c           	     ó  aaaa€ VP                  RR4      oSf   VP                  RR4      oSf   R# SP                  R^@4      oVVVV3R lp\        P                  ! V SSR,          SP                  RR4      VR	7       R# )
aQ  Apply quantization to a model if specified in config.

Args:
    model: The model to quantize
    config: Model config dict (should contain 'quantization' key if quantized)
    weights: Loaded weights dict (used to check which layers have scales)
    model_quant_predicate: Optional model-specific predicate for which layers to quantize
ÚquantizationNÚquantization_configÚ
group_sizec                 ó2  <€ \        VR 4      '       g   R# \        VR4      '       d,   VP                  P                  R,          S,          ^ 8w  d   R# Se+   S! W4      p\        V\        4      '       d   V# V'       g   R# V S9   d
   SV ,          # V  R2S9   # )Úto_quantizedFÚweightz.scaleséÿÿÿÿ)Úhasattrrn   Úshaper(   r   )ÚpÚmÚpred_resultrk   rd   ri   r^   s   && €€€€r   Úget_class_predicateÚ/apply_quantization.<locals>.get_class_predicateæ   sˆ   ø€ ä�q˜.×)Ò)Ùä�1�h×Ò A§H¡H§N¡N°2Õ$6¸Õ$CÀqÔ$HÙà Ò,Ù/°Ó5ˆKÜ˜+¤t×,Ò,Ø"Ð"ßÙà�ÔØ •?Ð"à��Gˆ} Ñ'Ð'r   ÚbitsÚmodeÚaffine)rk   rw   rx   Úclass_predicate)Úgetre   Úquantize)rb   rc   r^   rd   ru   rk   ri   s   &&ff @@r   Úapply_quantizationr}   Ñ   s€   û€ ð —:‘:˜n¨dÓ3€LØÒØ—z‘zÐ"7¸Ó>ˆØÒÙØ×!Ñ! ,°Ó3€J÷(ð (ô( ‡K‚KØØØ˜&Õ!Ø×Ñ˜f hÓ/Ø+÷r   c          
      ój   € V ^8„  d   QhR\         R\        \         ,          R\         R\        R\        /# )r   Ú
model_typeÚ
model_nameÚcategoryÚmodel_remappingr   )r6   r   r   r   )r   s   "r   r   r     s>   € ÷ ;ñ ;Üð;ä”S•	ð;ô ð;ô ð	;ô
 ñ;r   c           	     óF  € VP                  V R4      p\        \        4      P                  V,          R,          p. pVP	                  4       '       d„   VP                  4       '       dn   VP                  4        FY  pVP                  4       '       g   K  VP                  P                  R4      '       d   K>  VP                  VP                  4       K[  	  Ve)   W@8w  d#   V F  pW†9   d   Tp Wƒ9   g   K  W8,          p  M		  MVe   Tp  RV RV  2p	\        P                  ! V	4      p
W 3#   \         dm   pTP                  X	8w  d-   \        RRR7       \        R	T  R
T RTP                   24      ThRT  RT R2p\        P                  ! T4       \!        T4      hRp?ii ; i)aå  
Retrieve the model architecture module based on the model type and name.

Args:
    model_type: The type of model to load (e.g., "whisper", "voxtral").
    model_name: List of model name components for remapping hints.
    category: Either "tts" or "stt".
    model_remapping: Dictionary mapping model names to architecture names.

Returns:
    Tuple[module, str]: The imported architecture module and resolved model_type.

Raises:
    ValueError: If the model type is not supported.
NÚmodelsÚ__ú
mlx_audio.ú.models.Ú
T)Úflushz"
Missing dependency while loading z: z&
Please install it using: pip install zModel type z not supported for r9   )r{   r   Ú__file__ÚparentrG   Úis_dirÚiterdirr%   r=   ÚappendÚ	importlibÚimport_moduleÚImportErrorÚprintÚloggingÚerrorÚ
ValueError)r   r€   r�   r‚   Úmodel_type_mappedÚ
models_dirÚavailable_modelsÚitemÚpartÚmodule_pathÚarchÚeÚmsgs   &&&&         r   Úget_model_classrŸ     s•  € ð, (×+Ñ+¨J¸Ó=Ðô ”h“×&Ñ&¨Õ1°HÕ<€JØÐØ×Ñ×Ò˜z×0Ñ0×2Ò2Ø×&Ñ&Ö(ˆDØ�{‰{�}Œ} T§Y¡Y×%9Ñ%9¸$×%?Ô%?Ø ×'Ñ'¨¯	©	Ö2ñ )ð ÒÐ"3Ô"AÛˆDØÔ'Ø!�
ØÖ&Ø,Õ2�
Ùò ð 
Ò	&Ø&ˆ
ðØ" 8 *¨H°Z°LÐAˆÜ×&Ò& {Ó3ˆð ÐÐøô ô Ø�6‰6�[Ô Ü�$˜dÕ#äØ5°j°\ÀÀAÀ3ð G8Ø89¿¹°xðAóð ðð
 ˜J˜<Ð':¸8¸*ÀAÐFˆÜ�Š�cÔÜ˜‹oÐûðús   ÄD) Ä)F Ä4A'FÆF c                ó–   € V ^8„  d   QhR\         \        \        3,          R\        R\        R\        R\        R\
        P                  /# )r   rJ   r�   r‚   ÚlazyÚstrictr   )r   r6   r   r   r7   re   rf   )r   s   "r   r   r   A  sY   € ÷ _ñ _Ü”cœ4�iÕ ð_äð_ô ð_ô ð	_ô
 ð_ô ‡Y�Yñ_r   c                óö  € VP                  RR4      pVP                  RR4      pVP                  RR4      p\        V \        4      '       dD   Vf   \        V 4      pVP	                  RR4      p	VP	                  RR4      p
\        V V	V
VR7      p M=\        V \        4      '       d   Vf   \        V 4      pM\        R	\        V 4       24      h\        V 4      p\        V 4      VR
&   Vf   VP	                  RR4      pVf   VP	                  RR4      pVf   Ve   V^ ,          P                  4       MRpVR8X  d
   RV9   d   Rp\        VVVVR7      w  rÇ\        VR4      '       d   VP                  P                  V4      MTpVP                  V4      p\!        V 4      p\        VR4      '       d   VP#                  V4      p\%        VRR4      p\'        WëVV4       VP!                  \)        VP+                  4       4      VR7       V'       g%   \,        P.                  ! VP1                  4       4       VP/                  4        \        VP                  R4      '       d   VP                  P3                  Wà4      pV# )a  
Base implementation for loading models (shared between TTS, STT, and STS).

Args:
    model_path: The path or HuggingFace repo to load the model from.
    category: Either "tts" or "stt".
    model_remapping: Dictionary mapping model names to architecture names.
    lazy: If False, evaluate model parameters immediately.
    strict: If True, raise an error if any weights are missing.
    **kwargs: Additional keyword arguments (revision, force_download).

Returns:
    nn.Module: The loaded and initialized model.
Úmodel_name_partsNr   rD   rB   rC   F)rB   rC   rD   úInvalid model path type: rJ   ÚarchitectureÚllamaÚacoustic_dimÚtada)r   r€   r�   r‚   ÚModelConfigÚsanitizerd   )r¢   Úpost_load_hook)Úpopr(   r6   Úget_model_name_partsr{   rK   r   r•   r'   rU   ÚlowerrŸ   rp   rª   r)   ÚModelr`   r«   Úgetattrr}   ÚlistÚitemsr\   ÚevalÚ
parametersr¬   )rJ   r�   r‚   r¡   r¢   r+   r€   r   rD   rB   rC   rc   Úmodel_classÚmodel_configrb   r^   rd   s   &&&&&,           r   Úbase_load_modelr¸   A  sN  € ð, —‘Ð.°Ó5€JØ—‘˜L¨$Ó/€JØ—Z‘ZÐ 0°$Ó7€Nä�*œc×"Ò"ØÒÜ-¨jÓ9ˆJØ—:‘:˜j¨$Ó/ˆØŸ™Ð$4°eÓ<ˆÜ#ØØØ)Ø)ô	
‰
ô 
�J¤×	%Ò	%ØÒÜ-¨jÓ9ˆJøäÐ4´T¸*Ó5EÐ4FÐGÓHÐHä˜Ó$€FÜ˜z›?€Fˆ<Ñð ÒØ—Z‘Z ¨dÓ3ˆ
ØÒØ—Z‘Z °Ó5ˆ
ØÒØ.8Ò.D�Z •]×(Ñ(Ô*È$ˆ
ð �WÔ °6Ô!9Øˆ
ä-ØØØØ'ô	Ñ€Kô �; ×.Ò.ð 	×Ñ×)Ñ)¨&Ô1àð ð
 ×Ñ˜lÓ+€Eô ˜:Ó&€Gô ˆu�j×!Ò!Ø—.‘. Ó)ˆô $ EÐ+BÀDÓIÐÜ�u gÐ/DÔEà	×Ñ”t˜GŸM™M›OÓ,°VÐÔ<çÜ
�Š�× Ñ Ó"Ô#à	‡J�J„Lô ˆ{× Ñ Ð"2×3Ò3Ø×!Ñ!×0Ñ0°ÓCˆà€Lr   c                 ó.   € \         f	   ^ RIHp  V s \         # )zLazy load STT utils.©Úutils)Ú
_stt_utilsÚmlx_audio.sttr»   )Ú	stt_utilss    r   Ú_get_stt_utilsr¿   «  ó   € ô ÒÝ4àˆ
ÜÐr   c                 ó.   € \         f	   ^ RIHp  V s \         # )zLazy load TTS utils.rº   )Ú
_tts_utilsÚmlx_audio.ttsr»   )Ú	tts_utilss    r   Ú_get_tts_utilsrÅ   µ  rÀ   r   c                 ó.   € \         f	   ^ RIHp  V s \         # )zLazy load STS utils.rº   )Ú
_sts_utilsÚmlx_audio.stsr»   )Ú	sts_utilss    r   Ú_get_sts_utilsrÊ   ¿  rÀ   r   c                 ó.   € \         f	   ^ RIHp  V s \         # )zLazy load VAD utils.rº   )Ú
_vad_utilsÚmlx_audio.vadr»   )Ú	vad_utilss    r   Ú_get_vad_utilsrÏ   É  rÀ   r   c                 ó.   € \         f	   ^ RIHp  V s \         # )zLazy load LID utils.rº   )Ú
_lid_utilsÚmlx_audio.lidr»   )Ú	lid_utilss    r   Ú_get_lid_utilsrÔ   Ó  rÀ   r   c                ó$   € V ^8„  d   QhR\         /# )r   Úcoeff)Úfloat)r   s   "r   r   r   Ý  s   € ÷ 'ñ '¬ñ 'r   c                ó  € ^ RI pVP                  VP                  V 4      4      pVR,          R8  d#   \        VR,          R4      pW,          R,          p W3R8„  ,          pVP                  ^ ,          pV^
8:  d   V # VP                  V\        RV,          4      \        RV,          4       4      pWP                  W,          R^
R7      ,          p VP                  VP                  V 4      4      pV^8”  d	   W,          p V # )	zãNormalize the volume of an audio signal.

Args:
    audio: Input audio signal array (numpy array).
    coeff: Target coefficient for normalization, default is 0.2.

Returns:
    numpy array: The volume-normalized audio signal.
Ngš™™™™™¹?gü©ñÒMbP?g{®Gáz„?gÍÌÌÌÌÌì?g®Gáz®ï?)Úa_minÚa_maxro   )ÚnumpyÚsortÚabsÚmaxrq   ÚmeanÚintÚclip)ÚaudiorÖ   ÚnpÚtempÚscaling_factorÚLÚvolumeÚ	max_values   &&      r   Úaudio_volume_normalizeré   Ý  sà   € ó ð �7‰7�2—6‘6˜%“=Ó!€Dð ˆB…x�#„~Ü˜T "�X tÓ,ˆØÕ&¨Õ,ˆð �t‘Õ€DØ�
‰
�1�€Að 	ˆB„wØˆð �W‰W�Tœ#˜c A�g›,¬¨T°A­X«Ð7Ó8€Fð —G‘G˜E�N°#¸R�GÓ@Õ@€Eð —‘�r—v‘v˜e“}Ó%€IØ�1„}ØÕ!ˆà€Lr   c                ó$   € V ^8„  d   QhR\         /# )r   Úlength)rà   )r   s   "r   r   r     s   € ÷ (ñ (¬sñ (r   c           	     ó(  € ^ RI p^ RIpV P                  ^ ,          V8  d5   VP                  V ^ \	        WP                  ^ ,          ,
          4      34      p VP                  ^ V P                  ^ ,          V,
          4      p\	        WA,           4      pWV # )zÚGet a random audio segment of given length.

Args:
    audio: Input audio array (numpy array).
    length: Desired segment length (sample_rate * duration).

Returns:
    numpy array: Audio segment of specified length.
N)ÚrandomrÛ   rq   Úpadrà   Úrandint)râ   rë   rí   rã   Ústart_indexÚ	end_indexs   &&    r   Úrandom_select_audio_segmentrò     st   € ó ãà‡{�{�1…~˜ÔØ—‘�u˜q¤# f¯{©{¸1­~Õ&=Ó">Ð?Ó@ˆØ—.‘.  E§K¡K°¥N°VÕ$;Ó<€KÜ�KÕ(Ó)€Ià˜YÐ'Ð'r   c                óv   € V ^8„  d   QhR\         \        P                  R3,          R\        R\        R\        /# )r   râ   ú
np.ndarrayÚorig_sample_rateÚsample_rateÚaxis)r   r\   Úarrayrà   )r   s   "r   r   r     s>   € ÷ :ñ :Ü”—‘˜<Ð'Õ(ð:äð:ô ð:ô ñ	:r   c           	     ó  € ^ RI p^ RIp^ RIHp W8X  d   V # VP	                  V 4      pVP                  \        V4      \        V4      4      pW(,          p	W,          p
\        Wš4      p^@RRrípVP                  ^V,          V,          ^,           WÛ,          RV3R7      pVP                  VV	V
VVRR7      P                  VP                  R	R
7      p\        V \        P                  4      '       d   \        P                  ! V4      # V# )aà  Resample audio with polyphase filtering.

Uses a Kaiser-windowed sinc anti-aliasing filter equivalent to ``librosa``'s
``kaiser_best`` (resampy parameters) instead of ``resample_poly``'s default
Kaiser(5.0). The default filter has a wide transition band that leaves
significant energy near the new Nyquist; the sharper filter band-limits
cleanly so resampled audio matches the librosa-equivalent featurizers that
ASR reference pipelines (e.g. NeMo) assume. See issue #24.

Args:
    audio: Audio array as numpy or MLX.
    orig_sample_rate: Original sample rate.
    sample_rate: Target sample rate.
    axis: Axis containing the time dimension.

Returns:
    Audio resampled to ``sample_rate``. The return type matches the input type.
N)Úsignalgbé°Rî?gQaTiŠ-@Úkaiser)ÚwindowÚedge)r÷   rü   ÚpadtypeF©Úcopy)ÚmathrÛ   Úscipyrú   ÚasarrayÚgcdrà   rÞ   ÚfirwinÚresample_polyÚastypeÚfloat32r(   r\   rø   )râ   rõ   rö   r÷   r  rã   rú   Úaudio_npr  ÚupÚdownÚmax_rateÚ	num_zerosÚrolloffÚbetaÚfirÚ	resampleds   &&&&             r   Úresample_audior    s  € ó0 ãÝàÔ&Øˆà�z‰z˜%Ó €HØ
�(‰(”3Ð'Ó(¬#¨kÓ*:Ó
;€CØ	Õ	€BØÕ"€Dô
 �2‹}€HØ!Ð#5Ð7I˜€IØ
�-‰-Ø	ˆI�˜Õ  1Õ$ØÕØ˜$Ðð ó €Cð
 ×$Ñ$ØØ
ØØØØð %ó ÷ �fˆR�Z‰Z˜e€fÓ$ð ô �%œŸ™×"Ò"Ü�xŠx˜	Ó"Ð"ØÐr   c                óv   € V ^8„  d   QhR\         \        P                  R3,          R\        R\        R\        /# )r   râ   rô   Útop_dbÚframe_lengthÚ
hop_length)r   r\   rø   r×   rà   )r   s   "r   r   r   Z  s>   € ÷ $2ñ $2Ü”—‘˜<Ð'Õ(ð$2äð$2ô ð$2ô ñ	$2r   c                ó¸  € ^ RI pVP                  V 4      p^\        V4      V,
          V,          ,           pV^ 8:  d   V # TP                  \	        V4       Uu. uF@  pVP                  VP                  WWV,          Ws,          V,            ^,          4      4      NKB  	  up4      p^VP                  VP                  VR4      4      ,          p	VP                  V	4      V,
          p
VP                  Wš8¬  4      ^ ,          p\        V4      ^ 8X  d   V # \        V^ ,          4      p\        VR,          4      ^,           pWÃ,          p\        WÓ,          V,           \        V4      4      pW^V p\        V \        P                  4      '       d2   \        P                  ! VP                  VP                   RR7      4      # VP                  VP                   RR7      # u upi )zATrim leading/trailing low-energy regions using a simple RMS gate.Ng»½×Ùß|Û=Frÿ   ro   )rÛ   r  r>   rø   ÚrangeÚsqrtrß   Úlog10ÚmaximumrÞ   Úwhererà   Úminr(   r\   r  r  )râ   r  r  r  rã   r	  Ún_framesÚiÚrmsÚrms_dbÚ	thresholdÚ
non_silentÚstart_frameÚ	end_frameÚstart_sampleÚ
end_sampleÚtrimmeds   &&&&             r   Útrim_silencer)  Z  sˆ  € ó à�z‰z˜%Ó €HØ”C˜“M LÕ0°ZÕ?Õ?€HØ�1„}Øˆà
�(‰(ô
 ˜8”_ó		
ñ %�ð �G‰GØ—‘˜ Z¥°!µ.À<Õ2OÐPÐTUÕUÓVöñ %ñ		
ó€Cð �"—(‘(˜2Ÿ:™: c¨5Ó1Ó2Õ2€FØ—‘�v“ Õ'€IØ—‘˜&Ñ-Ó.¨qÕ1€JÜ
ˆ:ƒ˜!ÔØˆä�j •mÓ$€KÜ�J˜r•NÓ# aÕ'€IØÕ+€LÜ�YÕ+¨lÕ:¼CÀ»MÓJ€JØ JÐ/€Gä�%œŸ™×"Ò"Ü�xŠx˜Ÿ™ r§z¡z¸˜Ó>Ó?Ð?Ø�>‰>˜"Ÿ*™*¨5ˆ>Ó1Ð1ùò+	
s   ÁAGc                óÖ   € V ^8„  d   QhR\         \        \        P                  3,          R\        R\
        \        ,          R\        R\
        \        ,          R\        P                  /# )r   râ   rö   rë   Úvolume_normalizeÚsegment_durationr   )r   r6   r\   rø   rà   r   r7   )r   s   "r   r   r   �  se   € ÷ D/ñ D/Ü””b—h‘h�ÕðD/äðD/ô ”S�MðD/ô ð	D/ô
 œs•mðD/ô ‡X�XñD/r   c           	     ó*  € \        V \        P                  4      '       d   V # \        V \        4      '       g   \	        R\        V 4       24      h^ RIp^ RIp^ RIH	p VP                  P                  V 4      '       g   \        RV  24      hV! V 4      w  r‰VP                  p
\        V
4      ^8”  d"   VP                  ^R7      pWŠ^,          ,          pW8w  d   \!        W‰V4      pVe   \#        W,          4      p\%        W‹4      pV'       d   \'        V4      pVeS   VP                  ^ ,          V8”  d   VRV pM4VP)                  V^ \#        W(P                  ^ ,          ,
          4      34      p\        P                  ! V\        P*                  R7      # )a’  Load audio from file path or return mx.array as-is.

Args:
    audio: Audio input - can be:
        - str: Path to audio file (will be loaded and resampled to sample_rate)
        - mx.array: MLX array (returned as-is)
    sample_rate: Target sample rate (default 24000)
    length: Target length in samples (pad or truncate if specified)
    volume_normalize: Whether to normalize audio volume
    segment_duration: If specified, randomly select a segment of this duration (seconds)

Returns:
    mx.array: Audio waveform at target sample rate

Raises:
    FileNotFoundError: If audio file path does not exist
    TypeError: If audio is not str or mx.array
z#audio must be str or mx.array, got N)ÚreadzAudio file not found: )r÷   )Údtype)r(   r\   rø   r6   r#   r'   ÚosrÛ   Úmlx_audio.audio_ior.  r4   rG   rH   rq   r>   Úsumr  rà   rò   ré   rî   r  )râ   rö   rë   r+  r,  r0  rã   Ú
audio_readÚsamplesrõ   rq   Ú
seg_lengths   &&&&&       r   Ú
load_audior6  �  sN  € ô2 �%œŸ™×"Ò"Øˆä�eœS×!Ò!ÜÐ=¼dÀ5»k¸]ÐKÓLÐLããå5à�7‰7�>‰>˜%× Ò ÜÐ"8¸¸Ð @ÓAÐAá *¨5Ó 1Ñ€GØ�M‰M€Eô ˆ5ƒz�A„~Ø—+‘+ 1�+Ó%ˆØ !�HÕ$ˆð Ô&Ü  ¸KÓHˆð Ò#Ü˜Õ7Ó8ˆ
Ü-¨gÓBˆ÷ Ü(¨Ó1ˆð ÒØ�=‰=˜Õ˜fÔ$Ø˜g˜vÐ&‰Gà—f‘f˜W q¬#¨f·}±}ÀQÕ7GÕ.GÓ*HÐ&IÓJˆGä�8Š8�G¤2§:¡:Ô.Ð.r   c                ó0   € V ^8„  d   QhR\         R\        /# )r   r%   r   r5   )r   s   "r   r   r   è  s   € ÷ Yñ Yœsð Y¤tñ Yr   c                ó˜   € \        V \        4      ;'       d4    V P                  4       ;'       d    \        P                  ! V 4      '       * # )z0Check if a string is a valid Python module name.)r(   r6   ÚisidentifierÚkeywordÚ	iskeyword)r%   s   &r   Úis_valid_module_namer<  è  s7   € ä�dœCÓ ×XÐX T×%6Ñ%6Ó%8×XÐXÄ×ARÒARÐSWÓAXÔ=XÐXr   c                ó0   € V ^8„  d   QhR\         R\        /# )r   r›   r   r5   )r   s   "r   r   r   í  s   € ÷ ñ ¤3ð ¬4ñ r   c                 óæ   €  \         P                  P                  V 4      R J#   \         dC   pTP                  ;'       g    RpY8X  g   T P                  T R24      '       d    R p?R# h R p?ii ; i)NÚ r9   F)r�   ÚutilÚ	find_specÚModuleNotFoundErrorr%   r=   )r›   ÚexcÚmissing_names   &  r   Ú_has_model_modulerE  í  sd   € ðÜ�~‰~×'Ñ'¨Ó4¸DÐ@Ð@øÜô Ø—x‘x—~�~ 2ˆØÔ&¨+×*@Ñ*@ÀLÀ>ÐQRÐAS×*TÒ*TÝØûð	ús   ‚ # £A0®5A+Á*A+Á+A0c                óh   € V ^8„  d   QhR\         R\        \         ,          R\        \         ,          /# )r   r   r€   r   )r6   r   r   )r   s   "r   r   r   ÷  s)   € ÷ 2ñ 2¤3ð 2´D¼µIð 2Ä(Ì3Å-ñ 2r   c                ó  € \        4       p\        4       p\        4       p\        4       p\	        4       pV .T;'       g    . ,           pRVP
                  3RVP
                  3RVP
                  3RVP
                  3RVP
                  3.pV FY  w  ršW—9  d   K  V FF  pV
P                  W»4      p\        V4      '       g   K'  RV	 RV 2p\        V4      '       g   KB  V	u u # 	  K[  	  V FP  w  ršV FE  pWº9   g   K  W«,          p\        V4      '       g   K&  RV	 RV 2p\        V4      '       g   KA  V	u u # 	  KR  	  V FH  w  ršV F=  pWº9  g   K  \        V4      '       g   K  RV	 RV 2p\        V4      '       g   K9  V	u u # 	  KJ  	  R# )	zMDetermine whether a model belongs to the TTS, STT, STS, LID, or VAD category.ÚttsÚsttÚstsÚlidÚvadr†   r‡   N)	r¿   rÅ   rÊ   rÏ   rÔ   ÚMODEL_REMAPPINGr{   r<  rE  )r   r€   r¾   rÄ   rÉ   rÎ   rÓ   Ú
candidatesÚ
categoriesr�   ÚremapÚhintrœ   r›   s   &&            r   Úget_model_categoryrR  ÷  s�  € äÓ €IÜÓ €IÜÓ €IÜÓ €IÜÓ €Ià� ×!1Ð!1¨rÕ2€Jð 
�	×)Ñ)Ð*Ø	�	×)Ñ)Ð*Ø	�	×)Ñ)Ð*Ø	�	×)Ñ)Ð*Ø	�	×)Ñ)Ð*ð€Jó &‰ˆØÔ%ÙÛˆDØ—9‘9˜TÓ(ˆDÜ'¨×-Ò-ÙØ& x j°¸¸Ð?ˆKÜ  ×-Ô-Ø”ó ñ &ó &‰ˆÛˆDØŽ}Ø•{�Ü+¨D×1Ò1ÙØ *¨8¨*°H¸T¸FÐC�Ü$ [×1Ô1Ø#”Oó ñ &ó &‰ˆÛˆDØÖ Ô%9¸$×%?Ô%?Ø *¨8¨*°H¸T¸FÐC�Ü$ [×1Ô1Ø#”Oó	 ñ &ñ r   c                óh   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          /# rM   )r   r6   r   r   )r   s   "r   r   r   ,  s'   € ÷ +ñ +¤U¬3´¨9Õ%5ð +¼$¼s½)ñ +r   c                 ó`  € R p\        V \        4      '       d(   V P                  4       P                  R4      R	,          pMˆ\        V \        4      '       d\    V P
                  P                  R4      pV P
                  V^,           ,          P                  4       P                  R4      R	,          pM\        R\        V 4       24      h. p\        4       pVP                  R4       Uu. uF  qU'       g   K  VNK  	  ppV FÔ  pV'       d   WT9   d   K  VP                  V4       VP                  V4       RV9   dM   VP                  R4       F7  pV'       g   K  Wt9  g   K  VP                  V4       VP                  V4       K9  	  \        P                  ! RRV4      pV'       g   Kª  W„9  g   K²  VP                  V4       VP                  V4       KÖ  	  \        \!        V4      4       FŽ  p	\        V	^,           \!        V4      ^,           4       Fd  p
WiV
 pRP#                  V4      RP#                  V4      3 F7  pV'       g   K  WÄ9  g   K  VP                  V4       VP                  V4       K9  	  Kf  	  K�  	  V#   \         d    T P                  P                  4       p ELßi ; iu upi )
Nr:   Úhubz--r¥   Ú-Ú_z
[^a-z0-9]+r?  ro   )r(   r6   r¯   Úsplitr   ÚpartsÚindexr•   r%   r'   ÚsetrŽ   ÚaddÚreÚsubr  r>   Újoin)rJ   r€   rZ  rY  Úseenrš   Ú
dash_partsÚsubpartÚ
normalizedÚstartÚendÚsegmentÚcombineds   &            r   r®   r®   ,  s   € Ø€JÜ�*œc×"Ò"Ø×%Ñ%Ó'×-Ñ-¨cÓ2°2Õ6‰
Ü	�J¤×	%Ò	%ð	1Ø×$Ñ$×*Ñ*¨5Ó1ˆEØ#×)Ñ)¨%°!­)Õ4×:Ñ:Ó<×BÑBÀ4ÓHÈÕL‰Jô Ð4´T¸*Ó5EÐ4FÐGÓHÐHà€EÜ‹5€Dà#-×#3Ñ#3°CÔ#8ÓAÑ#8˜4»D—$�$Ñ#8€JÐAãˆß�t”|ÙØ�‰�TÔØ�‰�Œà�$Œ;ØŸ:™: cž?�ß‘7˜wÖ2Ø—L‘L Ô)Ø—H‘H˜WÖ%ñ +ô
 —V’V˜M¨2¨tÓ4ˆ
ß‰:˜*Ö0Ø�L‰L˜Ô$Ø�H‰H�ZÖ ñ ô" ”s˜:“Ö'ˆÜ˜ �¤C¨
£O°aÕ$7Ö8ˆCØ  sÐ+ˆGØ ŸX™X gÓ.°·±¸Ó0@ÓA�ß‘8 Ö 4Ø—L‘L Ô*Ø—H‘H˜XÖ&ó Bó 9ñ (ð €LøôG ô 	1Ø#Ÿ™×.Ñ.Ó0‹Jð	1üò Bs   ÁAI? Ã'	J+Ã5J+É?%J(Ê'J(c                ó$   € V ^8„  d   QhR\         /# )r   r€   )r6   )r   s   "r   r   r   Z  s   € ÷ -5ñ -5œ3ñ -5r   c                óX  € \        V 4      pRp \        V 4      pVP                  RR4      pVf   VP                  RR4      pVf   \	        4       P                  V4      p\        WQ4      pV'       g   Ve   Vh\        RV  24      hR\        4       P                  R\        4       P                  R\	        4       P                  R\        4       P                  R	\        4       P                  /pWg9  d   \        R
V R24      hWv,          ! V 4      #   \         d   p/ pTp Rp?EL
Rp?ii ; i)a  Load a TTS, STT, STS, LID, or VAD model based on its configuration and name.

Args:
    model_name (str): Name or path of the model to load

Returns:
    The loaded model instance

Raises:
    ValueError: If the model type cannot be determined or is not supported
Nr   r¦   z#Could not determine model type for rH  rI  rJ  rK  rL  zModel type 'z' not supported)r®   rU   rH   r{   rÊ   Úinfer_model_type_from_configrR  r•   rÅ   Ú
load_modelr¿   rÔ   rÏ   )r€   r¤   Ú
load_errorrc   rC  r   Úmodel_categoryÚmodel_loaderss   &       r   rk  rk  Z  s&  € ô ,¨JÓ7ÐØ€JðÜ˜ZÓ(ˆð —‘˜L¨$Ó/€JØÒØ—Z‘Z °Ó5ˆ
ØÒÜ#Ó%×BÑBÀ6ÓJˆ
Ü'¨
ÓE€NçØÒ!ØÐÜÐ>¸z¸lÐKÓLÐLð 	Œ~Ó×*Ñ*ØŒ~Ó×*Ñ*ØŒ~Ó×*Ñ*ØŒ~Ó×*Ñ*ØŒ~Ó×*Ñ*ð€Mð Ô*Ü˜<¨Ð'7°ÐGÓHÐHàÖ(¨Ó4Ð4øô9 ô ØˆØŽ
ûðús   �D ÄD)ÄD$Ä$D))z*.jsonrX   z*.pyz*.modelz
*.tiktokenz*.txtz*.jinjaz*.jsonlz*.yamlrY   z*.pth)NFN)N)FF)gš™™™™™É?)ro   )é   i   i   )iÀ]  NFN)r   r   r   r   r   r   r   r   r6  r  r)  ré   rò   r)   r<  rR  r®   rk  rK   rU   r`   r}   rŸ   r¸   )CÚ__doc__r!   rZ   r�   Úimportlib.utilrQ   r:  r“   r]  Úpathlibr   Útypingr   r   r   r   r   r   r	   r
   Úmlx.coreÚcorer\   Úmlx.nnre   Úhuggingface_hubr   Úmlx_audio.dspr   r   r   r   r   r   r   r   r   r)   rI   r?   rK   rU   r`   r}   rŸ   r¸   r¼   rÂ   rÇ   rÌ   rÑ   r¿   rÅ   rÊ   rÏ   rÔ   ré   rò   r  r)  r6  Ú__all__r<  rE  rR  r®   rk  r    r   r   Ú<module>rz     s  ðñó Û Û Û Û Û Û Û 	Ý ÷	÷ 	ó 	õ Ý Ý -÷	÷ 	ó 	ñ ˆCƒL€õ òLÐ õ÷,õ^Aõ0÷</õd;÷|_ðF €
Ø€
Ø€
Ø€
Ø€
òòòòò÷'õT(÷,:÷z$2÷ND/òN€õ@Yõ
õ2õj+÷\-5r   