
    ri%                         S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	J
r
JrJr  SSKJr  SSKJrJr  SSKJrJr  SS	KJrJr  \R0                  " 5       rSS
 jr\S:X  a  \" 5         gg)z)Flask web server with HTTP API for Piper.    N)Path)AnyDictListOptional)urlopen)Flaskrequest   )
PiperVoiceSynthesisConfig)VOICES_JSONdownload_voicec            	        ^	^
^^^^ [         R                  " 5       n U R                  SSSS9  U R                  S[        SSS9  U R                  S	S
SSS9  U R                  SS[        SS9  U R                  SS[        SS9  U R                  SS[        SS9  U R                  SSSS[        SS9  U R                  SSSS 9  U R                  S!S"[        S#S$S9  U R                  S%S&S'[        [        R                  " 5       5      /S(S)9  U R                  S*S+S,S-9  U R                  S.SS/S 9  U R                  5       m	[        R                  " T	R                  (       a  [        R                  O[        R                  S09  [        R                  T	5        T	R                  (       d  T	R                   S1   T	l        [        T	R                  5      m[        T	R"                  5      mTR%                  5       (       d_  T	R"                  nT	R                    HC  n[        U5      U S23-  n[        R                  S3U5        UR%                  5       (       d  MA  Um  O   TR%                  5       (       d  ['        S4T S535      eTR(                  R+                  S25      m
[,        R.                  " TT	R0                  S69mT
T0m[3        [4        5      nUR7                  S7S8/S99S:[8        [
        [:        4   4U	U4S; jj5       nUR7                  S<S8/S99S:[8        [
        [:        4   4S= j5       nUR7                  S>S?/S99S:[
        4U4S@ jj5       nUR7                  SAS?/S99S:[<        4U	U
UU4SB jj5       nUR?                  T	R@                  T	RB                  SC9  gD)EzRun HTTP server.z--hostz0.0.0.0zHTTP server host)defaulthelpz--porti  zHTTP server port)typer   r   z-mz--modelTzPath to Onnx model file)requiredr   z-sz	--speakerzId of speaker (default: 0))r   r   z--length-scalez--length_scalezPhoneme lengthz--noise-scalez--noise_scalezGenerator noisez--noise-w-scalez--noise_w_scalez	--noise-wz	--noise_wzPhoneme width noisez--cuda
store_truezUse GPU)actionr   z--sentence-silencez--sentence_silenceg        z&Seconds of silence after each sentencez
--data-dirz
--data_dirappendzJData directory to check for downloaded models (default: current directory))r   r   r   z--download-dirz--download_dirz1Path to download voices (default: first data dir))r   z--debugzPrint DEBUG messages to console)levelr   .onnxzChecking '%s'zUnable to find voice: z (use piper.download_voices)use_cudaz/voicesGET)methodsreturnc                    > 0 n [        T S35      /nTR                   HZ  n[        U5      R                  S5       H9  n[        U S35      nUR                  5       (       d  M(  UR	                  U5        M;     M\     U HQ  nUR
                  R                  S5      nXP;   a  M%  [        USSS9 n[        R                  " U5      X'   SSS5        MS     U $ ! , (       d  f       Mf  = f)zList downloaded voices.

Outputs a JSON object with the format:
{
  "<voice name>": { <voice config> },
  ...
}

for each voice in your data directories.
z.jsonz*.onnxz
.onnx.jsonrzutf-8)encodingN)
r   data_dirglobexistsr   namerstripopenjsonload)	voices_dictconfig_pathsr"   	onnx_pathconfig_pathmodel_idconfig_fileargs
model_paths	          W/home/kim/smarthome/piper_models/venv/lib/python3.13/site-packages/piper/http_server.py
app_voicesmain.<locals>.app_voicesj   s     ')$(J<u)=$>#?H!(^00:	"i[#67%%'' ''4 ; & (K"''..|<H&k39[(,		+(>% :9 (  :9s   /C
C%	z/all-voicesc                      [        [        5       n [        R                  " U 5      sSSS5        $ ! , (       d  f       g= f)zList all Piper voices.

Outputs voices.json from the piper-voices repo on HuggingFace.
See: https://huggingface.co/rhasspy/piper-voices
N)r   r   r(   r)   )responses    r2   app_all_voicesmain.<locals>.app_all_voices   s&     [!X99X& "!!s   0
>z	/downloadPOSTc                     > [         R                  " [        R                  5      n U R	                  S5      nU(       d  [        S5      eU R	                  SS5      n[        UTUS9  U$ )a|  Download a voice.

Downloads the .onnx and .onnx.json file from piper-voices repo on HuggingFace.
See: https://huggingface.co/rhasspy/piper-voices

Expects a JSON object with the format:
{
  "voice": "<voice name>",   (required)
  "force_redownload": false  (optional)
}

Returns the name of the voice.
Voice format must be <language>-<name>-<quality> like "en_US-lessac-medium".
voicezvoice is requiredforce_redownloadF)r<   )r(   loadsr
   dataget
ValueErrorr   )r>   r.   r<   download_dirs      r2   app_downloadmain.<locals>.app_download   sX      zz',,'88G$01188$6>x@PQ    /c                    > [         R                  " [        R                  5      n U R	                  SS5      R                  5       nU(       d  [        S5      e[        R                  U 5        U R	                  ST5      nTR	                  U5      nUcu  TR                   He  n[        U5      U S3-  nUR                  5       (       d  M+  [        R                  SU5        [        R                  " UTR                  S9nUTU'     O   Uc  [        R                  S	U5        TnU R	                  S
5      nUR                   R"                  S:  a  Uc  U R	                  S5      nU(       a%  UR                   R$                  R	                  U5      nUcN  [        R                  SUUR                   R$                  R'                  5       5        TR(                  =(       d    SnUb  XcR                   R"                  :  a  Sn[+        U[-        U R	                  STR.                  b  TR.                  OUR                   R.                  5      5      [-        U R	                  STR0                  b  TR0                  OUR                   R0                  5      5      [-        U R	                  STR2                  b  TR2                  OUR                   R2                  5      5      S9n[        R                  SX5        [4        R6                  " 5        n	[8        R:                  " U	S5      n
U
   Sn[=        UR?                  X5      5       H  u  pU(       dS  U
RA                  URB                  5        U
RE                  URF                  5        U
RI                  URJ                  5        SnUS:  aG  U
RM                  [O        [Q        UR                   RB                  TRR                  -  S-  5      5      5        U
RM                  URT                  5        M     SSS5        U	RW                  5       sSSS5        $ ! , (       d  f       N'= f! , (       d  f       g= f)a  Synthesize audio from text.

Expects a JSON object with the format:
{
  "text": "Text to speak.",      (required)
  "voice": "<voice name>",       (optional)
  "speaker": "<speaker name>",   (optional)
  "speaker_id": "<speaker id>",  (optional, overrides speaker)
  "length_scale": 1.0,           (optional)
  "noise_scale": 0.667,          (optional)
  "length_w_scale": 0.8          (optional)
}
text zNo text providedr;   Nr   zLoading voice %sr   z)Voice not found: %s. Using default voice.
speaker_idr   speakerzSpeaker not found: '%s' in %sr   length_scalenoise_scalenoise_w_scale)rI   rK   rL   rM   z&Synthesizing text: '%s' with config=%swbFT   ),r(   r=   r
   r>   r?   stripr@   _LOGGERdebugr"   r   r$   r   r)   cudawarningconfignum_speakersspeaker_id_mapkeysrJ   r   floatrK   rL   rM   ioBytesIOwaver'   	enumerate
synthesizesetframeratesample_ratesetsampwidthsample_widthsetnchannelssample_channelswriteframesbytesintsentence_silenceaudio_int16_bytesgetvalue)r>   rG   r.   r;   r"   maybe_model_pathrI   rJ   
syn_configwav_iowav_filewav_params_setiaudio_chunkr0   default_model_iddefault_voiceloaded_voicess                 r2   app_synthesizemain.<locals>.app_synthesize   su    zz',,'xx#))+/00d88G%56!!(+= MM#'>xj4F#F #**,,MM"4h?&OO,<tyyQE.3M(+ * =OOGR!E$(HH\$:
LL%%)
0Bhhy)G"\\88<<WE
!3LL//446
 "\\.Q
"ll6O6O)OJ$!"  ,,8 ))"\\66	 !  ++7 (("\\55	  #  --9 **"\\77	- 

D 	>QZZ\V(,		&$(?H!&&/0@0@0R&SNA) --k.E.EF --k.F.FG --k.I.IJ)-1u ,,! #$)LL$<$<t?T?T$TWX$X!" (()F)FG! 'T ( ??$- \ \s%   P: C(P)P:)
P7	3P::
Q)hostportN)"argparseArgumentParseradd_argumentrg   rY   strr   cwd
parse_argsloggingbasicConfigrR   DEBUGINFOrQ   rA   r"   modelr$   r@   r%   r&   r   r)   rS   r	   __name__router   r   rf   runrw   rx   )parser
voice_namer"   rk   appr3   r7   rB   ru   r0   rr   rs   rA   rt   r1   s            @@@@@@r2   mainr      s   $$&F
):LM
sD?QR
i$=VW
k:VW
*=M   u;L   "   IF
5   TXXZ!Y   @   ,-N   Dtzzgmmw||LMM$ MM!,))*L djj!JZZ
H#H~:,e0DDMM/+;<&&((-
 & $ZL0LM
 	
 "--g6 OOJCM,<m+LM /CYYy5'Y*S#X  +< 	YY}ugY.'DcN ' /' 	YY{VHY-#  .2 	YYsVHY%n%E n% n% &n%` GGG+rD   __main__)r   N)__doc__ry   rZ   r(   r   r\   pathlibr   typingr   r   r   r   urllib.requestr   flaskr	   r
   rH   r   r   download_voicesr   r   	getLoggerrQ   r   r    rD   r2   <module>r      sU    /  	     , , "   ) 8



J,Z zF rD   