
    ,/2j                    0   d Z ddlm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  ed          ZdZg d	Zd
Zd4dZdZdZdZdZdZd\  ZZd\  ZZd\  ZZd\  ZZ d\  Z!Z"Z#dZ$d\  Z%Z&Z'd5dZ(eedd6d#Z)d7d&Z*d' Z+	 d8d9d1Z,	 	 d:d;d3Z-dS )<u  火山引擎(豆包)大模型语音合成 —— V3 WebSocket 双向流式二进制协议。

文档:wss://openspeech.bytedance.com/api/v3/tts/bidirection(用户提供)。
对外:`synthesize(text, voice) -> mp3 bytes`(同步,内部跑 asyncio)。引擎线程可直接调。
鉴权(旧版控制台):X-Api-App-Id + X-Api-Access-Key + X-Api-Resource-Id(seed-tts-1.0/2.0)。
帧:4 字节 header + [event int32] + [id_len+id] + payload_len + payload;整数大端。
    )annotationsN)Path)Optional)
get_loggerz	voice.ttsz5wss://openspeech.bytedance.com/api/v3/tts/bidirection)%zh_male_M392_conversation_wvae_bigttszh_female_cancan_mars_bigtts$zh_male_ahu_conversation_wvae_bigtts$zh_female_shuangkuaisisi_moon_bigtts!zh_male_beijingxiaoye_moon_bigtts"zh_female_wanwanxiaohe_moon_bigtts"zh_male_jingqiangkanye_moon_bigtts%zh_female_tianmeixiaoyuan_moon_bigttszh_male_changtianyi_mars_bigttsseatintreturnstrc                    t          |           dk    rt          S t          t          |           dz
  t          t                    z           S )Nr      )r   JUDGE_VOICEVOICESlen)r   s    1/root/genesis-world/src/genesis/voice/volc_tts.pyvoice_for_seatr   '   s7    
4yyA~~3t99q=CKK/00    r   	            )r   r   )r      )2   3   )d   f   )            )i^  i_  i`  tuple[str, str]c                 d   t          j        d          t          j        d          }} | r|st          t                                                    j        d         dz  }|                                r|                    d                                          D ]}}|	                                }|
                    d          r| p|                    dd	          d	         } J|
                    d
          r|p|                    dd	          d	         }~| r|st          d          | |fS )uC   从环境或 .env 读 VOLC_APP_ID / VOLC_ACCESS_TOKEN(不回显)。VOLC_APP_IDVOLC_ACCESS_TOKEN   z.envutf-8)encodingzVOLC_APP_ID==r   zVOLC_ACCESS_TOKEN=u3   缺少 VOLC_APP_ID / VOLC_ACCESS_TOKEN(请配 .env))osgetenvr   __file__resolveparentsexists	read_text
splitlinesstrip
startswithsplitRuntimeError)appidtokenenvflns       r   _credsrA   =   s)   9]++RY7J-K-K5E 9e 9H~~%%''/2V;;;== 	9nngn66AACC 9 9XXZZ==00 9!8RXXc1%5%5a%8EE]]#788 9!8RXXc1%5%5a%8E Re RPQQQ%<r   )msg_typeserialevent
session_idOptional[str]bytesc                  t          d|dz  t          z  |dz  dz  dg          }|t          j        d|           z  }|=|                    d          }|t          j        dt          |                    |z   z  }|t          k    r)t          j        |d                              d          n|}|t          j        dt          |                    |z   z  }|S )	N   r   r   >ir.   >IF)ensure_ascii)	rG   
FLAG_EVENTstructpackencoder   SER_JSONjsondumps)rD   rE   payloadrB   rC   outsidbodys           r   _framerX   N   s    
'(a-:)ERSWXGXZ[\
]
]C6;tU###C((v{4S**S00FLPXFXFX4:gE22299'BBB^eD6;tSYY''$..CJr   datadictc                   | d         dz	  dz  }| d         dz  }| d         dz  }d}d }|t           z  r+t          j        d| ||dz                      d         }|dz  }|t          k    rht          j        d| ||dz                      d         }|dz  }t          j        d| ||dz                      d         }|dz  }d||| |||z            d	S t          j        d| ||dz                      d         }|dz  }||z  }t          j        d| ||dz                      d         }|dz  }| |||z            }	|dk    r|	rt	          j        |	          }	|t          k    rd
nd||	dS )Nr   r   r   r    rJ   r   rK   error)kindrD   coderT   audioserver)r]   rD   rT   )rM   rN   unpackMT_ERRORgzip
decompressMT_AUDIO_ONLY)
rY   rB   flagscompressoffrD   r^   plenidlenrT   s
             r   _parserk   Y   s   Q1$HGdNEAw~H
CEz DdDS1W$566q93!838}T4C!G#455a8#(#}T4C!G#455a8#(#%$sSVY]S]~J^___M$Sq[ 12215Esaxs5LC=tCaK011!4DcQhc3sTz>"G6g/'**'=88GGhQVcjkkkr   c                   K   ddl }	 |                    t          | d           d{V S # t          $ r& |                    t          | d           d{V cY S w xY w)uO   websockets 版本兼容:新版用 additional_headers,旧版用 extra_headers。r   N)additional_headersmax_size)extra_headersrn   )
websocketsconnectWS_URL	TypeError)headersrp   s     r   _connectru   n   s      V''7UY'ZZZZZZZZZ V V V''gPT'UUUUUUUUUUUVs   "+ -AAmp3]  textvoicer=   r>   resource_idfmtsample_ratec                  K   |||t          t          j                              d}t          t          j                              }||d}	t                      }
t	          |           d {V }	 |                    t          t          d i                      d {V  t          |	                                 d {V           }|d         t          k    rt          d|           |                    t          t          |ddit          d||	dd	                     d {V  t          |	                                 d {V           }|d         t          k    r.t          d
|                    dd          d d                    |                    t          t          |ddit          d| ||	dd	                     d {V  |                    t          t           |i                      d {V  	 t          |	                                 d {V           }|d         dk    r)t          d|d          d|d         d d                    |d         dk    r|d         t"          k    r|
|d         z  }
|d         t$          k    r t          d
|d         d d                    |d         t&          k    rn	 |                    t          t(          d i                      d {V  n# t*          $ r Y nw xY w|                                 d {V  n# |                                 d {V  w xY wt/          |
          S )N)zX-Api-App-IdzX-Api-Access-KeyzX-Api-Resource-IdzX-Api-Connect-Id)formatr|   rD   u   建连失败:uidgenesisBidirectionalTTS)speakeraudio_params)userrD   	namespace
req_paramsu   会话失败:rT   r   r(   )rx   r   r   Tr]   r\   u   TTS 错误 code=r^    r_   )r   uuiduuid4	bytearrayru   sendrX   EV_START_CONNrk   recvEV_CONN_STARTEDr<   EV_START_SESSIONEV_SESSION_STARTEDgetEV_TASK_REQUESTEV_FINISH_SESSIONEV_TTS_RESPONSEEV_SESSION_FAILEDEV_SESSION_FINISHEDEV_FINISH_CONN	ExceptioncloserG   )rx   ry   r=   r>   rz   r{   r|   rt   rV   apr_   wsrs                r   _synthesizer   w   s     $%$/SEVEVX XG
djll

C	4	4BKKE  	 	 	 	 	 	 Bggf]D"55666666666??????##W:((2q22333ggf-sI&1APb&+R@@5B 5B C C D D 	D 	D 	D 	D 	D 	D 	D ??????##W:+++LquuY/D/DTcT/JLLMMMggf_cI&Oa#'E2NN4P 4P Q Q R R 	R 	R 	R 	R 	R 	R 	R ggf.R88999999999		RWWYY''AyG##"#Vai#V#V!I,tPStBT#V#VWWWyG##'
o(E(E9%z..."#G1Y<3E#G#GHHHz000			''&r::;;;;;;;;;; 	 	 	D	 hhjjbhhjj<<s1   1IL! /K6 5L! 6
L L! LL! !L=r   c                    t                      \  }}|pt          j        d          pd}t          j        t          | ||||||                    S )ut   文本 → 音频字节(同步)。fmt=mp3/pcm/ogg_opus。resource_id 默认 VOLC_TTS_RESOURCE_ID 或 seed-tts-1.0。VOLC_TTS_RESOURCE_IDzseed-tts-1.0)rA   r1   r2   asynciorunr   )rx   ry   rz   r{   r|   r=   r>   rids           r   
synthesizer      sO     88LE5

L#9::
LnC;{4uc3TTUUUr   )r   r   r   r   )r   r)   )rD   r   rE   rF   r   rG   )rY   rG   r   rZ   )rv   rw   )rx   r   ry   r   r=   r   r>   r   rz   r   r{   r   r|   r   r   rG   )r   Nrv   rw   )rx   r   ry   r   rz   rF   r{   r   r|   r   r   rG   ).__doc__
__future__r   r   rc   rR   r1   rN   r   pathlibr   typingr   genesis.obs.logging_setupr   loggerrr   r   r   r   MT_FULL_CLIENTMT_FULL_SERVERre   rb   rM   rQ   SER_RAWr   r   r   EV_CONN_FAILEDr   r   r   r   r   r   EV_TTS_SENTENCE_STARTEV_TTS_SENTENCE_ENDr   rA   rX   rk   ru   r   r    r   r   <module>r      s    # " " " " "    				               0 0 0 0 0 0	K	 	 	@
 
 
 01 1 1 1 
" ' !% ~"( &. # #=J : '):>K ; *O   " HV^f      l l l l*V V V <A' ' ' ' 'T (FW\V V V V V V Vr   