
    Pi0                         d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ  G d
 de          ZdS )#Festival backend for the phonemizer    N)Logger)Path)OptionalDictListIOUnionPattern)BaseBackend)lispy)	Separator)get_package_resourceversion_as_tuplec                       e Zd ZdZdZ	 	 	 d%dedeeeef                  de	dee
         f fdZed	             Zed
efd            Zedefd            Zed             Zed             Zedeeef         fd            Zdee         dedede	dee         f
dZededefd            Zedefd            Zedee         fd            ZdefdZedededefd            Zedee         dede	defd            Z ed eee                  dede	defd!            Z!edede	defd"            Z"ed#edede	dee         fd$            Z# xZ$S )&FestivalBackendr   NFlanguagepunctuation_markspreserve_punctuationloggerc                    t                                          ||||           | j                            d|                                            t          d          }t          |d          5 }|                                | _        d d d            n# 1 swxY w Y   | j                            d|           d S )N)r   r   r   zfestival executable is %szfestival/phonemize.scmrz	loaded %s)	super__init__r   debug
executabler   openread_script)selfr   r   r   r   script_filefscript	__class__s          x/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/phonemizer/backend/festival/festival.pyr   zFestivalBackend.__init__*   s     	/!5	 	 	 	 	 	5t7H7HIII ++CDD+s## 	*w"<<>>DL	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*+{33333s   3BB Bc                      dS )Nfestival r'       r$   namezFestivalBackend.name<   s    zr(   r   c                     |	d| _         dS t          j        |          }|                                rt	          j        |t          j                  st          | d          |                                | _         dS )a  Sets the festival backend to use `executable`

        If this is not set, the backend uses the default festival executable
        from the system installation.

        Parameters
        ----------
        executable (str) : the path to the festival executable to use as
            backend. Set `executable` to None to restore the default.

        Raises
        ------
        RuntimeError if `executable` is not an executable file.

        N is not an executable file)	_FESTIVAL_EXECUTABLEpathlibr   is_fileosaccessX_OKRuntimeErrorresolveclsr   s     r$   set_executablezFestivalBackend.set_executable@   s    " '+C$F\*--
""$$ 	;:rw)G)G 	;999; ; ; $.#5#5#7#7   r(   returnc                    | j         r| j         S dt          j        v rt          j        t          j        d                   }|                                r t          j        |t          j                  st          d| d          |	                                S t          j        d          }|st          d          t	          |          	                                S )av  Returns the absolute path to the festival executable used as backend

        The following precedence rule applies for executable lookup:

        1. As specified by FestivalBackend.set_executable()
        2. Or as specified by the environment variable
           PHONEMIZER_FESTIVAL_EXECUTABLE
        3. Or the default 'festival' binary found on the system with ``shutil.which('festival')``


        Raises
        ------
        RuntimeError
            if the festival executable cannot be found or if the
            environment variable PHONEMIZER_FESTIVAL_EXECUTABLE is set to a
            non-executable file

        PHONEMIZER_FESTIVAL_EXECUTABLE)modezPHONEMIZER_FESTIVAL_EXECUTABLE=r+   r&   z"failed to find festival executable)r,   r/   environr-   r   r.   r0   r1   r2   r3   shutilwhichr4   s     r$   r   zFestivalBackend.executable\   s    ( # 	,+++rz99 bj*J'L M MJ &&((2	*27;;;2 #1j 1 1 12 2 2 %%'''\*--
 	646 6 6J'')))r(   c                 T    	 |                                   n# t          $ r Y dS w xY wdS )z=True if the festival executable is available, False otherwiseFT)r   r2   )r5   s    r$   is_availablezFestivalBackend.is_available   sA    	NN 	 	 	55	ts    
%%c                 X   |                                  }t          j        |dg                              d                                          }d}	 t          j        ||                              d          }n!# t          $ r t          d|           dw xY wt          |          S )zFestival version as a tupe of integers (major, minor, patch)

        Raises
        ------
        RuntimeError if FestivalBackend.is_available() is False or if the
            version cannot be extracted for some reason.

        z	--versionlatin1z.* ([0-9\.]+[0-9]):   z%cannot extract festival version from N)r   
subprocesscheck_outputdecodestriprematchgroupAttributeErrorr2   r   )r5   r&   long_versionfestival_version_reversions        r$   rM   zFestivalBackend.version   s     >>## ".{#% %%+VH%5%5eegg 	 5	Nh2LAAGGJJGG 	N 	N 	NBBBD DIMN	N  (((s   (A< <Bc                  
    ddiS )zA dictionnary of language codes -> name supported by festival

        Actually only en-us (American English) is supported.

        zen-usz
english-usr'   r'   r(   r$   supported_languagesz#FestivalBackend.supported_languages   s     &&r(   textoffset	separatorrF   c                     |                      |          }t          |          dk    rg S |                     |          }|                     |||          }|S )a  Return a phonemized version of `text` with festival

        This function is a wrapper on festival, a text to speech
        program, allowing simple phonemization of some English
        text. The US phoneset we use is the default one in festival,
        as described at http://www.festvox.org/bsv/c4711.html

        Any opening and closing parenthesis in `text` are removed, as
        they interfer with the Scheme expression syntax. Moreover
        double quotes are replaced by simple quotes because double
        quotes denotes utterances boundaries in festival.

        Parsing a ill-formed Scheme expression during post-processing
        (typically with unbalanced parenthesis) raises an IndexError.

        r   )_preprocesslen_process_postprocess)r    rP   rQ   rR   rF   s        r$   _phonemize_auxzFestivalBackend._phonemize_aux   sX    " %%t99>>I}}T""  y%88r(   linec                     d| z   dz   S )z4Return the string `line` surrounded by double quotes"r'   rY   s    r$   _double_quotedzFestivalBackend._double_quoted   s     TzCr(   c                     t          |           t          d          k    rd} |                     dd                              dd                              dd                                          S )z+Remove 'forbidden' characters from the line' r[   ())setreplacerF   r\   s    r$   _cleanedzFestivalBackend._cleaned   sb    
 t99C  D ||C$$,,S"55==c2FFLLNNNr(   c                 b      fd|D             }d                      fd|D                       S )a  Returns the contents of `text` formatted for festival input

        This function adds double quotes to begining and end of each
        line in text, if not already presents. The returned result is
        a multiline string. Empty lines in inputs are ignored.

        c              3   N   K   | ]}|d k                         |          V   dS r`   N)re   .0rY   r5   s     r$   	<genexpr>z.FestivalBackend._preprocess.<locals>.<genexpr>   s<       ? ?#'42::CLL::::? ?r(   
c              3   N   K   | ]}|d k                         |          V   dS rh   )r]   ri   s     r$   rk   z.FestivalBackend._preprocess.<locals>.<genexpr>   sB       M M)-Ct$$M Mr(   )join)r5   rP   cleaned_texts   `  r$   rT   zFestivalBackend._preprocess   ss    ? ? ? ?+/? ? ? yy M M M M1=M M M M M 	Mr(   c                 p   t          j        dd          5 }	 |                    |           |                                 |j        }t
          j        dk    r|                    dd          }t          j        dd          5 }	 |                    | j        	                    |                     |                                 | 
                                 d|j         }| j        r| j                            d|           t          j        d          5 }|                     ||          cd	d	d	           t          j        |j                   cd	d	d	           t          j        |j                   cd	d	d	           S # 1 swxY w Y   	 t          j        |j                   n# t          j        |j                   w xY w	 d	d	d	           n# 1 swxY w Y   t          j        |j                   n# t          j        |j                   w xY w	 d	d	d	           d	S # 1 swxY w Y   d	S )
a  Return the raw phonemization of `text`

        This function delegates to festival the text analysis and
        syllabic structure extraction.

        Return a string containing the "SylStructure" relation tree of
        the text, as a scheme expression.

        zw+F)deletewin32\z\\z -b z
running %sN)tempfileNamedTemporaryFilewritecloser)   sysplatformrd   r   formatr   r   r   TemporaryFile_run_festivalr/   remove)r    rP   datar)   scmcmdfstderrs          r$   rV   zFestivalBackend._process   s    (e<<< 	%%

4   

 y<7**<<f55D0eDDD ,,		$,"5"5d";";<<<		!%!2!2BBBB; A K--lC@@@ &3D99 DW#'#5#5c7#C#CD D D D D D D 	#(+++#, , , , , , ,& 	$)$$$=	% 	% 	% 	% 	% 	% 	% 	%2D D D D D D D D D 	#(++++	#(+++++#, , , , , , , , , , , , , , ,& 	$)$$$$	$)$$$$$=	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	%s   H+A,G?GBF/F	2F/>GG?#H+	FF/FF/G/G

GG?G	G?!G	"G?%H+?HH++H/2H/r   r   c           
      b   	 t          j        t          j        | d          |          }t	          j        dd|                    d                    S # t           j        $ rJ}|                    d           t          d|  d	|j
         d
|                                           dd}~ww xY w)zRuns the festival command for phonemization

        Returns the raw phonemized output (need to be postprocesses). Raises a
        RuntimeError if festival fails.

        F)posix)stderrz + rA   r   z	Command "z" returned exit status z, output is:
N)rC   rD   shlexsplitrG   subrE   CalledProcessErrorseekr2   
returncoder   )r   r   outputerrs       r$   r|   zFestivalBackend._run_festival  s    	;,Cu---g? ? ?F 6$V]]8%<%<===, 	; 	; 	;LLOOO0C 0 0 0 0&||~~0 01 16:;	;s   AA B.$AB))B.syllc                     |j         }d | dd         D             }|                    d |D                       }|r|n||z   S )z3Parse a syllable from festival to phonemized outputc              3   Z   K   | ]&}|d          d                               dd          V  'dS )r   r[   r`   N)rd   )rj   phones     r$   rk   z4FestivalBackend._postprocess_syll.<locals>.<genexpr>/  s:      BBuQx{""3++BBBBBBr(   rB   Nc              3   &   K   | ]}|d k    |V  dS rh   r'   )rj   os     r$   rk   z4FestivalBackend._postprocess_syll.<locals>.<genexpr>0  s&      11Qbq11r(   )r   rn   )r   rR   rF   sepouts        r$   _postprocess_syllz!FestivalBackend._postprocess_syll+  sY     oBBabbBBBhh11#11111*sss*r(   wordc                 ~     j         }|                     fd|dd         D                       }r|n||z   S )z/Parse a word from festival to phonemized outputc              3   F   K   | ]}                     |          V  d S )N)r   )rj   r   r5   rR   rF   s     r$   rk   z4FestivalBackend._postprocess_word.<locals>.<genexpr>7  sI       " " !!$	599" " " " " "r(   rB   N)syllablern   )r5   r   rR   rF   r   r   s   ` ``  r$   _postprocess_wordz!FestivalBackend._postprocess_word3  so      hh " " " " " "QRR" " " " " *sss*r(   c                     |j         }g }t          j        |          D ]4}|                     |||          }|dk    r|                    |           5|                    |          }|r|n||z   S )z/Parse a line from festival to phonemized outputr`   )r   r   parser   appendrn   )r5   rY   rR   rF   r   r   r   s          r$   _postprocess_linez!FestivalBackend._postprocess_line<  s~     nK%% 	! 	!D((y%@@Drzz

4   hhsmm*sss*r(   treec                 N      fd|                     d          D             S )z8Conversion from festival syllable tree to desired formatc                 F    g | ]}|d v                     |          S ))r`   z(nil nil nil))r   )rj   rY   r5   rR   rF   s     r$   
<listcomp>z0FestivalBackend._postprocess.<locals>.<listcomp>L  sA     6 6 6444 %%dIu==444r(   rl   )r   )r5   r   rR   rF   s   ` ``r$   rW   zFestivalBackend._postprocessI  sF    6 6 6 6 6 6 JJt,,6 6 6 	6r(   )NFN)%__name__
__module____qualname____doc__r,   strr   r
   r   boolr   r   staticmethodr)   classmethodr6   r   r   r?   rM   r   rO   r   intr   rX   r]   re   rT   rV   r	   r|   r   r   r   rW   __classcell__)r#   s   @r$   r   r   #   s{       --   EI.3,04 4 4$,U3<-@$A4'+4 "&)4 4 4 4 4 4$   \ 8 8 8 8 [86 &*4 &* &* &* [&*P   [ ) ) [)6 'c3h ' ' ' \'49 c i X\ aefiaj    0  S  S       \  	Os 	O 	O 	O \	O MtCy M M M [M(%S (% (% (% (%T ;3 ; ; ; ; ; \;( +S	 +i + +QT + + + \+ +T$s)_ + +SW +\_ + + + [+ 
+S 
+D 
+S 
+ 
+ 
+ [
+ 6 6	 6$ 64PS9 6 6 6 [6 6 6 6 6r(   r   )r   r/   r-   rG   r   r<   rC   rx   rt   loggingr   r   typingr   r   r   r	   r
   r   phonemizer.backend.baser   phonemizer.backend.festivalr   phonemizer.separatorr   phonemizer.utilsr   r   r   r'   r(   r$   <module>r      s8   * ) 				  				       



              ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; / / / / / / - - - - - - * * * * * * C C C C C C C Ck6 k6 k6 k6 k6k k6 k6 k6 k6 k6r(   