
    i-                        S r SSKrSSKrSSKJr  SSKJr   " S S5      r\S:X  a  \" 5       r	Sr
S	r/ S
Qr\" S5        \" S\
 S35        \" S\ S35        \" S5        \ Hb  u  rr\	R!                  \\
\5      r\	R%                  \5      r\" S\ S35        \" S\ 35        \" S\S 35        \" S\S S35        \" S5        Md     gg)a  Text duration estimation for TTS generation.

Provides ``RuleDurationEstimator``, which estimates audio duration from text
using character phonetic weights across 600+ languages. Used by
``OmniVoice.generate()`` to determine output length when no duration is specified.
    N)	lru_cache)Optionalc                   h    \ rS rSrS r\" SS9S 5       rS r  SS\S\S	\	S
\
\	   S\	S\	4S jjrSrg)RuleDurationEstimator   c                     0 SS_SS_SS_SS_SS_S	S
_SS_SS
_SS_SS_SS_SS_SS_SS_SS_SS_SS_SSSS.EU l         / SQU l        U R                   Vs/ s H  oS   PM	     snU l        g s  snf )Ncjkg      @hangulg      @kanag@ethiopicyiindicg?thai_lao      ?khmer_myanmararabichebrewlatin      ?cyrillicgreekarmeniangeorgianpunctuationg      ?spaceg?g      @        )digitmarkdefault)X)i  r   )i  r   )i/  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i	  r   )i	  r   )i
  r   )i
  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r
   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i?  r   )i_  r   )i  r   )i  r   )i  r   )i  r   )iO  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )iO  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i  r   )i0  r   )i0  r   )i/1  r	   )i1  r
   )i  r	   )iϤ  r   )i  r   )i?  r   )i  r   )i  r   )i  r   )i/  r   )i  r   )iߨ  r   )i  r   )i/  r   )i_  r   )i  r
   )iߩ  r   )i  r   )i_  r   )i  r   )iߪ  r   )i  r   )i/  r   )io  r   )i  r   )i  r   )i  r
   )i  r	   )i  r   )io  r   )i  r   )i  r   r   )weightsrangesbreakpoints)selfrs     4/mnt/workspace/OmniVoice/omnivoice/utils/duration.py__init__RuleDurationEstimator.__init__    s   
3
 c	

 C
 
 #
 S
 
 S
 c
 c
  S!
" #
$ S%
& '
( )
, 3-
. S/
0 5
DY
t +/++6+QaD+66s   A/i   )maxsizec                 x   [        U5      nSUs=::  a  S::  d  O  SUs=::  a  S::  a  O  OU R                  S   $ US:X  a  U R                  S   $ US:X  a  U R                  S	   $ [        R                  " U5      nUR	                  S
5      (       a  U R                  S	   $ UR	                  S5      (       d  UR	                  S5      (       a  U R                  S   $ UR	                  S5      (       a  U R                  S   $ UR	                  S5      (       a  U R                  S   $ [
        R                  " U R                  U5      nU[        U R                  5      :  a:  U R                  U   S   nU R                  R                  XPR                  S   5      $ US:  a  U R                  S   $ U R                  S   $ )z,Determines the weight of a single character.A   Z   a   z   r       r   i@  r   MPSr   ZNr      r   i   r	   )ordr    unicodedatacategory
startswithbisectbisect_leftr"   lenr!   get)r#   charcoder7   idxscript_types         r%   _get_char_weight&RuleDurationEstimator._get_char_weight   s    4y$"""3"3<<((2:<<(( 6><<''''-s##<<''s##x':':3'?'?<<..s##<<((s##<<((   !1!148T[[!!++c*1-K<<##Ki1HII '><<&&||I&&    c                 .   ^  [        U 4S jU 5       5      $ )z,Sums up the normalized weights for a string.c              3   F   >#    U  H  nTR                  U5      v   M     g 7f)N)rA   ).0cr#   s     r%   	<genexpr>?RuleDurationEstimator.calculate_total_weight.<locals>.<genexpr>   s     :T4((++Ts   !)sum)r#   texts   ` r%   calculate_total_weight,RuleDurationEstimator.calculate_total_weight   s    :T:::rC   target_textref_textref_durationlow_thresholdboost_strengthreturnc                     US::  d  U(       d  gU R                  U5      nUS:X  a  gXc-  nU R                  U5      nX-  n	Ub  X:  a  SU-  n
XIU-  U
-  -  $ U	$ )a  

Args:
    target_text (str): The text for which we want to estimate the duration.
    ref_text (str): The reference text that was used to measure
        the ref_duration.
    ref_duration (float): The actual duration it took
        to speak the ref_text.
    low_threshold (float): The minimum duration threshold below which the
        estimation will be considered unreliable.
    boost_strength (float): Controls the power-curve boost for short durations.
        Higher values boost small durations more aggressively.
        1 = no boost (linear), 2 = sqrt-like

Returns:
    float: The estimated duration for the target_text based
        on the ref_text and ref_duration.
r   r   r   )rL   )r#   rN   rO   rP   rQ   rR   
ref_weightspeed_factortarget_weightestimated_durationalphas              r%   estimate_duration'RuleDurationEstimator.estimate_duration   s{    4 1H00:
?!033K@*9$);)K.(E $F5#PPP%%rC   )r"   r!   r    N)2      )__name__
__module____qualname____firstlineno__r&   r   rA   rL   strfloatr   rZ   __static_attributes__ rC   r%   r   r      sx    C7J t$' $'L; *, !)&)& )& 	)&
  )& )& 
)& )&rC   r   __main__zHello, world.r   ))zHindi (With complex marks)u%   नमस्ते दुनिया)zArabic (With vowels)u)   مَرْحَبًا بِالْعَالَم)zVietnamese (Lots of diacritics)u   Chào thế giới)Chineseu   你好，世界！)zMixed Emojiu   Hello 🌍! This is fun 🎉z--- Reference ---zReference Text: ''zReference Duration: sz------------------------------[]zText: zTotal Weight: z.2fzEstimated Duration: z s)__doc__r9   r6   	functoolsr   typingr   r   r^   	estimatorref_txtref_dur
test_casesprintlangtxtrZ   est_timerL   weightre   rC   r%   <module>rx      s   $    Z& Z&@ z%'IGGJ 

	gYa
()	 	
+,	(O	c..sGWE11#6$qksenvcl+,$XcN"56h  ' rC   