
    Oju                    *   d Z ddlmZ ddlZddlmZ ddlmZ ddlZ	ej                  j                  dd      j                         Zej                  j                  d      xs dZ ed	d
      Zd Z G d d      Z G d d      Z G d d      Zd Zy)uP  Local speech-to-text on Apple Silicon.

Default engine: parakeet-mlx (NVIDIA Parakeet TDT 0.6b v3 on MLX) —
~24x realtime on an M4, utterance finals in 0.2-0.5s. English + European
languages only.

Set STT=whisper to use mlx-whisper large-v3-turbo instead: ~2x slower
finals but supports Arabic (language via STT_LANG, default auto).
    )annotationsN)ThreadPoolExecutorwrapsSTTparakeetSTT_LANG   zmlx-stt)max_workersthread_name_prefixc                .     t                fd       }|S )z<Run the wrapped method on the dedicated MLX thread and wait.c                 R    t        j                  g| i |j                         S N_MLXsubmitresult)akfns     7/Users/ahmed/devFolder/Ultron/claude-voice/voice/stt.pywrapz_on_mlx.<locals>.wrap    s%    {{2''Q'..00    r   )r   r   s   ` r   _on_mlxr      s    
2Y1 1Kr   c                  &    e Zd ZddZedd       Zy)ParakeetSTTc                X     d fd}t         j                  |      j                          y )Nc            	     *   dd l m}  ddlm} | _         |d      _        j
                  j                         5 }|j                  | j                  t        j                  dt        j                                     d d d        y # 1 sw Y   y xY wNr   )from_pretrainedz"mlx-community/parakeet-tdt-0.6b-v3>  dtypemlx.corecoreparakeet_mlxr    _mx_modeltranscribe_stream	add_audioarraynpzerosfloat32mxr    tselfs      r   _loadz#ParakeetSTT.__init__.<locals>._load(   s_    !4DH)*NODK..0ABHHRXXe2::%FGH 100   AB		BreturnNoner   r3   r4   s   ` r   __init__zParakeetSTT.__init__'   s     	I 	E!!#r   c                    | j                   j                         5 }|j                  | j                  j	                  |             |j
                  j                  j                         cddd       S # 1 sw Y   yxY w)z!audio: 1-D float32 mono @ 16 kHz.Nr)   r*   r+   r(   r,   r   textstripr3   audior2   s      r   
transcribezParakeetSTT.transcribe3   O     [[**,KKu-.88==&&( -,,   AA33A<Nr6   r@   z
np.ndarrayr7   str)__name__
__module____qualname__r:   r   rA    r   r   r   r   &   s    
$ ) )r   r   c                  p    e Zd ZdZd
dZddZd
dZed
d       Zedd       Z	edd       Z
edd       Zy	)StreamingParakeetSTTu>  Live streaming STT (Parakeet). Feed audio chunks WHILE the user talks
    (feed() returns the growing partial), then finalize() at end-of-utterance —
    so the final transcript is ready the instant they stop, and the HUD can show
    words as they're spoken. Falls back to batch transcribe() for other callers.
    c                t     d fd}d  _         d  _        t        j                  |      j	                          y )Nc            	     *   dd l m}  ddlm} | _         |d      _        j
                  j                         5 }|j                  | j                  t        j                  dt        j                                     d d d        y # 1 sw Y   y xY wr   r$   r0   s      r   r4   z,StreamingParakeetSTT.__init__.<locals>._loadC   s_    !4DH)*NODK..0ABHHRXXe2::%FGH 100r5   r6   )_cm_streamr   r   r   r9   s   ` r   r:   zStreamingParakeetSTT.__init__B   s.    	I E!!#r   c                    | j                   y| j                   j                  j                  j                         }	 | j                  j                  d d d        d | _         d | _        |S # t        $ r Y w xY w)N )rO   r   r=   r>   rN   __exit__	Exception)r3   r=   s     r   _finalize_implz#StreamingParakeetSTT._finalize_implS   sq    <<||""''--/	HHdD$/ 	  		s   A* *	A65A6c                    | j                          | j                  j                         | _        | j                  j	                         | _        y r   )rT   r)   r*   rN   	__enter__rO   r3   s    r   _start_implz StreamingParakeetSTT._start_impl_   s6    ;;002xx))+r   c                $    | j                          y)z1Open a fresh streaming session for one utterance.N)rX   rW   s    r   startzStreamingParakeetSTT.startd   s     	r   c                $   | j                   | j                          | j                   j                  | j                  j	                  t        j                  |                   | j                   j                  j                  j                         S )z@Add a chunk of new audio; return the current partial transcript.)
rO   rX   r+   r(   r,   r-   ascontiguousarrayr   r=   r>   )r3   r@   s     r   feedzStreamingParakeetSTT.feedi   sc     <<txx~~b.B.B5.IJK||""''--//r   c                "    | j                         S )z2Return the final transcript and close the session.)rT   rW   s    r   finalizezStreamingParakeetSTT.finalizeq   s     ""$$r   c                    | j                   j                         5 }|j                  | j                  j	                  |             |j
                  j                  j                         cddd       S # 1 sw Y   yxY w)z0Batch fallback (same as ParakeetSTT.transcribe).Nr<   r?   s      r   rA   zStreamingParakeetSTT.transcribev   rB   rC   Nr6   )r7   rE   rD   )rF   rG   rH   __doc__r:   rT   rX   r   rZ   r]   r_   rA   rI   r   r   rK   rK   ;   sf    $"
,
   0 0 % % ) )r   rK   c                  *    e Zd ZdZddZedd       Zy)
WhisperSTTz$mlx-community/whisper-large-v3-turboc                X     d fd}t         j                  |      j                          y )Nc                     dd l } | _        j                  j                  t        j                  dt        j
                        j                  t        xs d       y )Nr   r!   r"   enpath_or_hf_repolanguage)mlx_whisper_whisperrA   r-   r.   r/   MODEL_LANG)rj   r3   s    r   r4   z"WhisperSTT.__init__.<locals>._load   sC    'DMMM$$bjj14::$ % r   r6   r   r9   s   ` r   r:   zWhisperSTT.__init__   s    	 	E!!#r   c                    | j                   j                  || j                  t              }|d   j	                         S )Nrg   r=   )rk   rA   rl   rm   r>   )r3   r@   outs      r   rA   zWhisperSTT.transcribe   s;    mm&&4:: ' 
 6{  ""r   Nr6   rD   )rF   rG   rH   rl   r:   r   rA   rI   r   r   rc   rc   ~   s     2E
$ # #r   rc   c                     t         dk(  r
t               S t        j                  j	                  dd      dk(  r
t               S t               S )NwhisperSTT_LIVE01)_ENGINErc   osenvirongetrK   r   rI   r   r   load_sttry      s:    )|	zz~~j#&#-#%%=r   )ra   
__future__r   rv   concurrent.futuresr   	functoolsr   numpyr-   rw   rx   lowerru   rm   r   r   r   rK   rc   ry   rI   r   r   <module>r      s    # 	 1  
**..

+
1
1
3


z"*d aIF) )*@) @)F# #.r   