+
    i\in?                     &   ^ RI t ^ RIt^ RIt^ RIt^ RIHtHtHt ^ RIH	t
 ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHt ^RIHt ^RIHt RR R lltRR	 R
 lltR R ltRR R lltRR R lltR R ltRR R lltR t R t!]"R8X  d
   ]!! 4        R# R# )    N)OptionalTupleUnion)sliding_window_view)resample)AudioPlayer)
load_modelc                t    V ^8  d   QhR\         R\        R\        R\        R\        R\        P                  /# )   
audio_pathsample_ratelengthvolume_normalizesegment_durationreturn)strintboolmxarray)formats   "n/Users/agent/.cache/uv/archive-v0/6ZL4-8mCcRNgGE9wi6M6J/lib/python3.14/site-packages/mlx_audio/tts/generate.py__annotate__r      sH     & &&& & 	&
 & XX&    c           	         \         P                  ! V 4      w  rVVP                  p\        V4      ^8  d"   VP	                  ^R7      pWW^,          ,          pW8w  dH   \        RV RV 24       VP                  ^ ,          V,          p\        W,          4      p	\        WY4      pVe   \        W,          4      p
\        WZ4      pV'       d   \        V4      pVe   \        VP                  ^ ,          V,
          4      R8  g   Q hVP                  ^ ,          V8  d   VRV pM9\        P                  ! V^ \        W%P                  ^ ,          ,
          4      34      p\        P                  ! V\        P                  R7      pV# )   axiszResampling from z to Ni  )dtype)sfreadshapelensumprintr   r   random_select_audio_segmentaudio_volume_normalizeabsnppadr   r   float32)r   r   r   r   r   samplesorig_sample_rater"   durationnum_samples
seg_lengthaudios   &&&&&       r   
load_audior2      s?    !#
 3GMME 5zA~++1+%!H$& !1 2${mDE==#&66(0170#78
-gB (17==#f,-444==f$gv&GffWq#f}}Q7G.G*H&IJGHHWBJJ/ELr   c                d    V ^8  d   QhR\         P                  R\        R\         P                  /# )r   r1   coeffr   )r)   ndarrayfloat)r   s   "r   r   r   ;   s)     ( ("** (U (RZZ (r   c                8   \         P                  ! \         P                  ! V 4      4      pVR,          R8  d#   \        VR,          R4      pW,          R,          p W"R8  ,          pVP                  ^ ,          pV^
8:  d   V # \         P
                  ! V\        RV,          4      \        RV,          4       4      pV \         P                  ! W,          R^
R7      ,          p \         P                  ! \         P                  ! V 4      4      pV^8  d	   W,          p V # )z
Normalize the volume of an audio signal.

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

Returns:
    numpy array: The volume-normalized audio signal.
皙?gMbP?{Gz??gGz?)a_mina_max)r)   sortr(   maxr"   meanr   clip)r1   r4   tempscaling_factorLvolume	max_values   &&     r   r'   r'   ;   s     77266%=!D Bx#~Hd
 &, tD

1A 	Bw WWT#cAg,TAX78F BGGEN#R@@E rvve}%I1}!Lr   c                d    V ^8  d   QhR\         P                  R\        R\         P                  /# )r   r1   r   r   )r)   r5   r   )r   s   "r   r   r   f   s)     ( (rzz (3 (2:: (r   c           	     ,   V P                   ^ ,          V8  d:   \        P                  ! V ^ \        WP                   ^ ,          ,
          4      34      p \        P
                  ! ^ V P                   ^ ,          V,
          4      p\        W!,           4      pWV # )zget an audio segment given the length

Args:
    audio (np.ndarray):
    length (int): audio length = sampling_rate * duration
)r"   r)   r*   r   randomrandint)r1   r   start_index	end_indexs   &&  r   r&   r&   f   sn     {{1~uq#f{{1~&=">?@..EKKNV$;<KK()IY''r   c                    V ^8  d   QhR\         P                  R\        R\        R\        R\        R\        \        \        3,          /# )r   wavr   window_durationenergy_thresholdmargin_factorr   )r)   r5   r   r6   r   )r   s   "r   r   r   u   sP     * *	** * 	*
 * 38_*r   c           
     >   \        W!,          4      pWE,          pV^
,          p\        W4      RRV1,          p\        P                  ! \        P                  ! V^,          ^R7      4      p	W8  p
\        P
                  ! V
4      '       g   \        R4      h\        ^ \        P                  ! V
4      V,          V,
          4      p\        \        V 4      \        V
4      ^,
          \        P                  ! V
RRR1,          4      ,
          V,          V,           4      pW3# )a   Detect the start and end points of speech in an audio signal using RMS energy.

Args:
    wav: Input audio signal array with values in [-1, 1]
    sample_rate: Audio sample rate in Hz
    window_duration: Duration of detection window in seconds
    energy_threshold: RMS energy threshold for speech detection
    margin_factor: Factor to determine extra margin around detected boundaries

Returns:
    tuple: (start_index, end_index) of speech segment

Raises:
    ValueError: If the audio contains only silence
Nr   z*No speech detected in audio (only silence)r=   )r   r   r)   sqrtr@   any
ValueErrorr?   argmaxminr#   )rN   r   rO   rP   rQ   window_sizemargin	step_sizewindowsenergyspeech_maskstartends   &&&&&        r   detect_speech_boundariesr`   u   s    , o34K(Fr!I "#3KiK@G WWRWWWaZa01F,K66+EFF299[)I5>?E
C	[	A			+dd*; <	<	IFRC
 :r   c          
      |    V ^8  d   QhR\         P                  R\        R\        R\        R\         P                  /# )r   rN   r   rO   volume_thresholdr   )r)   r5   r   r6   )r   s   "r   r   r      sB      	  	
 ZZr   c                &    \        WW#4      w  rEWV # )a  Remove silence from both ends of an audio signal.

Args:
    wav: Input audio signal array
    sample_rate: Audio sample rate in Hz
    window_duration: Duration of detection window in seconds
    volume_threshold: Amplitude threshold for silence detection

Returns:
    np.ndarray: Audio signal with silence removed from both ends

Raises:
    ValueError: If the audio contains only silence
)r`   )rN   r   rO   rb   r^   r_   s   &&&&  r   remove_silence_on_both_endsrd      s!    ( */JE S>r   c                0    V ^8  d   QhR\         R\         /# )r   pitchr   )r6   )r   s   "r   r   r      s       % r   c                \    R\         P                  ! ^V R,          ,           4      ,          pV# )z
Converts a frequency from the Hertz scale to the Mel scale.

Parameters:
- pitch: float or ndarray
    Frequency in Hertz.

Returns:
- mel: float or ndarray
    Frequency in Mel scale.
i#
  i  )r)   log10)rf   mels   & r   hertz_to_melrj      s$     !eck/*
*CJr   c          (         V ^8  d   QhR\         R\        \        \         \        P                  3,          ,          R\
        R\         R\        R\         R\        \        ,          R\        \
        ,          R	\        \         ,          R
\        \         ,          R\        \        \         \        P                  3,          ,          R\         R\         R\        R\        R\        R\        R\        R\        RR/# )r   textmodel
max_tokensvoicespeed	lang_code	cfg_scale
ddpm_steps	ref_audioref_text	stt_modelfile_prefixaudio_format
join_audioplayverbosetemperaturestreamstreaming_intervalr   N)r   r   r   nnModuler   r6   r   )r   s   "r   r   r      s    n n
nE#ryy.)*n n 	n
 n n n n }n smn c299n-.n n n n n  !n" #n$ %n& 'n* 
+nr   c                z	    T;'       g    TpVf   \        R4      hV
f   V'       d   V	f   \        R4      h\        V\        4      '       d   \        VR7      pV'       Ed"   \        P
                  P                  V4      '       g   \        RV 24      hRp\        VR4      '       d   VP                  R8X  d   R	p\        WP                  VR
7      pV	'       g   ^ RIpRVP                  VP                  4      P                  9   d{   \!        R4       ^ RIHp \        V
\        4      '       d   VP'                  V
R7      MT
p
V
P                  V4      P(                  p	?
\*        P,                  ! 4        \!        RV	 24       V'       d   \/        VP                  R7      MRp\!        RV  RV RV RV 24       \1        R?RV RVRVRVRVRV	RVRVRVRVRVRVR V/VB pVP                  ! R?/ VB p. pV R!V 2p\3        V4       EF  w  ppV'       d   VP5                  VP6                  4       V'       d   VP9                  VP6                  4       MMV'       gF   V R"VR# R!V 2p\:        P<                  ! VVP6                  VP                  4       \!        R$V 24       V'       g   K  \!        R%4       \!        R&VP>                   24       \!        R'VP@                  R(,          R) 24       \!        R*VPB                   R+VPD                  R,,          R) R-24       \!        R.VP@                  R/,           R0VP@                  R(,          R) R124       \!        R2VPF                  R3 R424       \!        R5VPH                  R3 R624       \!        R7VPJ                  R3 R824       EK  	  V'       d~   V'       gv   V'       d   \!        R9\M        V4       R:24       \*        PN                  ! V^ R;7      p\:        P<                  ! V R!V 2VVP                  4       V'       d   \!        R$V 24       V'       d#   VPQ                  4        VPS                  4        R# R#   \T         d%   p\!        R<T 24       \!        R=4        Rp?R# Rp?i\V         d.   p\!        R>T 24       ^ RI,p T P[                  4         Rp?R# Rp?ii ; i)@a  
Generates audio from text using a specified TTS model.

Parameters:
- text (str): The input text to be converted to speech.
- model (str): The TTS model to use.
- voice (str): The voice style to use.
- temperature (float): The temperature for the model.
- speed (float): Playback speed multiplier.
- lang_code (str): The language code.
- ref_audio (mx.array): Reference audio you would like to clone the voice from.
- ref_text (str): Caption for reference audio.
- stt_model_path (str): A mlx whisper model to use to transcribe.
- file_prefix (str): The output file path without extension.
- audio_format (str): Output audio format (e.g., "wav", "flac").
- join_audio (bool): Whether to join multiple audio files into one.
- play (bool): Whether to play the generated audio.
- verbose (bool): Whether to print status messages.
- model (object): A already loaded model.
- stt_model (object): A already loaded stt model.
Returns:
- None: The function writes the generated audio to a file.
Nz.Model path or model instance must be provided.zISTT model path or model instance must be provided when ref_text is given.)
model_pathz Reference audio file not found: F
model_typesparkT)r   r   ru   z-Ref_text not found. Transcribing ref_audio...)Model)path_or_hf_repoz[94mRef_text:[0m )r   z[94mText:[0m z
[94mVoice:[0m z
[94mSpeed:[0m zx
[94mLanguage:[0m rl   ro   rp   rq   rt   rr   rs   r|   rn   r{   r}   r~   ._03du0   ✅ Audio successfully generated and saving as: z
==========zDuration:              zSamples/sec:           zsamples-per-secz.1fzPrompt:                z	 tokens, ztokens-per-secz tokens-per-seczAudio:                 r,   z
 samples, z samples-per-seczReal-time factor:      z.2fxzProcessing time:       szPeak memory usage:     GBzJoining z audio filesr   zImport error: zIThis might be due to incorrect Python path. Check your project structure.zError loading model:  ).rU   
isinstancer   r	   ospathexistsFileNotFoundErrorhasattrr   r2   r   inspect	signaturegenerate
parametersr%   mlx_audio.stt.models.whisperr   from_pretrainedrl   r   clear_cacher   dict	enumeratequeue_audior1   appendr    writeaudio_durationaudio_samplestoken_countpromptreal_time_factorprocessing_time_secondspeak_memory_usager#   concatenatewait_for_drainstopImportError	Exception	traceback	print_exc)!rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   kwargs	normalizer   Whisperplayer
gen_kwargsresults
audio_list	file_nameiresultr1   er   s!   &&&&&&&&&&&&&&&&&&&,             r   generate_audior      s   ZA~~v=MNN)0@[  eS!!%0E 977>>),,'*J9+(VWWIul++0@0@G0K 	"'8'89I !2!25>>!B!M!MMIJM &i55  //	/J& 
  )11)<AAH!NN$5hZ@A @D):):;#D6 *%%*G ,%%*G ,((1{4	
  


 
  	

  
 
  
 "
 $
 "
 
 
  2
 

" ...:.
"m1\N3	"7+IAv""6<<0!!&,,/*m1QsG1\NC	FLL&2D2DEHTUwl#/0E0E/FGH-f.B.BCT.UVY-Z[ -f.@.@-A6==YiKjknJoo~ -f.B.B9.M-NjY_YmYmn  ZA  BE  YF  FV  W /0G0G/LANO/0N0Ns/SSTUV/0H0H/MRPQ5 ,8 fZ 1>?NN:A6EHH-q/!!
 HTU!!#KKM   
qc"#W	
 	
  %aS)*	sz   Q Q 9Q #$Q DQ B+Q 8#Q A
Q +D Q ,Q 4Q <AQ Q 1 Q R: Q??R:R:"R55R:c                  *   \         P                  ! R R7      p V P                  R\        RRR7       V P                  R\        RRR	7       V P                  R
\        RRR	7       V P                  R\        RRR	7       V P                  R\
        RRR	7       V P                  R\
        RRR	7       V P                  R\        RRR	7       V P                  R\
        RRR	7       V P                  R\        RRR	7       V P                  R\
        RRR	7       V P                  R\        R R!R	7       V P                  R"\        R#R$R	7       V P                  R%R&R'R(7       V P                  R)R&R*R(7       V P                  R+R&R,R(7       V P                  R-\        R.R/R	7       V P                  R0\        RR1R	7       V P                  R2\        RR3R	7       V P                  R4\        R5R6R	7       V P                  R7\
        R8R9R	7       V P                  R:\
        R;R<R	7       V P                  R=\        ^2R>R	7       V P                  R?\
        R@RAR	7       V P                  RBR&RCR(7       V P                  RD\
        RERFR	7       V P                  4       pVP                  f   \        P                  P                  4       '       g4   \        P                  P                  4       P                  4       Vn        V# \        RG4       \        RH4      P                  4       Vn        V# )Iz#Generate audio from text using TTS.)descriptionz--modelTzPath or repo id of the model)typerequiredhelpz--max_tokens  z$Maximum number of tokens to generate)r   defaultr   z--textNz1Text to generate (leave blank to input via stdin)z--voicez
Voice namez--exaggerationg      ?z!Exaggeration factor for the voicez--cfg_scaleg      ?uH   Classifier-free guidance scale. Lower (≈1.0-1.5) is often more stable.z--ddpm_stepszFOverride diffusion steps. Higher = better quality, slower (try 30-50).z--speed      ?zSpeed of the audioz--gendermalez"Gender of the voice [male, female]z--pitchzPitch of the voicez--lang_codeenzLanguage codez--file_prefixr1   zOutput file name prefixz	--verbose
store_truezPrint verbose output)actionr   z--join_audiozJoin all audio files into onez--playzPlay the output audioz--audio_formatrN   zOutput audio formatz--ref_audiozPath to reference audioz
--ref_textzCaption for reference audioz--stt_model$mlx-community/whisper-large-v3-turboz.STT model to use to transcribe reference audioz--temperatureffffff?zTemperature for the modelz--top_pr:   zTop-p for the modelz--top_kzTop-k for the modelz--repetition_penaltyg?z Repetition penalty for the modelz--streamz8Stream the audio as segments instead of saving to a filez--streaming_interval       @z3The time interval in seconds for streaming segmentsz"Please enter the text to generate:z> )argparseArgumentParseradd_argumentr   r   r6   
parse_argsrl   sysstdinisattyr!   stripr%   input)parserargss     r   r   r   }  s\   $$1VWF
+	   3	   @	   	TM
0	   W	   U	   	sAUV
f3W   	sAUV
COT
c79R   L?UV
|2Q   <ST
sE8M   C4M   33P   6=	   eS7R   	sAVW
	R>ST
/	   G  
 B	   Dyyyy!!		(..0DI
 K 67d))+DIKr   c                  B    \        4       p \        R/ \        V 4      B  R # )Nr   )r   r   vars)r   s    r   mainr     s    <D T$Z r   __main__)i]  NFN)g?)r8   r9   r   )r8   r9   )Nr   af_heartr   r   NNNNr   r1   rN   FFTr   Fr   )#r   r   rI   r   typingr   r   r   mlx.corecorer   mlx.nnr   numpyr)   	soundfiler    numpy.lib.stride_tricksr   scipy.signalr   audio_playerr   utilsr	   r2   r'   r&   r`   rd   rj   r   r   r   __name__r   r   r   <module>r      sw     	  
 ) )     7 ! % &R(V(*Z4 nbeP!
 zF r   