11 KiB
同声翻译改走微软端到端
2026-10-18。只覆盖翻译页的同声模式(
simultaneous)。本文只做设计,不改代码。 端到端依据 iOS 集成文档《同声传译简介》第 9.3、9.6 节。拼接时的识别依据安卓海外文档《实时语音转写》第 8.2、9.3 节(iOS《实时语音转写简介》只写了微软模式必填language_name,没有语种表)。合成依据安卓海外文档《在线语音合成》的微软发音人表。 同声这一条覆盖 科大讯飞SparkChain-全面替换第三方-落地文档.md 第 5.1 节里「表外拆成星火听写」的写法。面对面、通话、音视频、EMAI 不在本文范围。
结论
两端语种都在微软同传表里:只开一条 AST,机房 RegionMSFT(安卓 RegionType.MSFT_TYPE)。识别、翻译、合成由这一条会话完成。
源或目标是中文、粤语、爱尔兰语:微软同传表没有这三语,改走拼接。拼接的识别必须是微软实时转写 RTASR(RegionMSFT),用 language_name 指定语种。不要用星火听写 ASR(zh_cn / cn_cbm / iat),也不要用新加坡、欧洲机房那两张转写表(ist_open、ist_mul_sp、ga_IE)。
拼接的合成用 OnlineTTS(RegionMSFT),发音人用微软神经音色。不要用 xiaoyan、x_xiaoyan、x_Catherine,也不要打 tts-api.xfyun.cn。
现在为什么一种声音念所有语言
同声在讯飞听写成功之后,是三段接起来的,没有用到 AST。
_startSparkListen调SparkChainSession.startListen,只做听写。- 整句文本再走原来的翻译。
playTranslatedText算出的voiceName在_sparkListen分支被丢掉,_playSparkTts只把目标语种短码传给SparkChainSession.speak。
原生合成不看音色表:
| 端 | 英语 | 其余语种 |
|---|---|---|
iOS ClassicTts,打 tts-api.xfyun.cn |
x2_catherine |
xiaoyan |
Android OnlineTTS |
x_Catherine |
x_xiaoyan(爱尔兰语例外,用 ga-IE-OrlaNeural) |
日语、韩语、法语都会用中文晓燕念出来。getIflytekTTSLanguageSpecs() 里按语种分好的发音人没有接到这条播报上。那张表是讯飞发音人,本方案也不再用。
目标链路
麦克风 PCM 仍由现在的耳机麦或手机麦采集,SDK 不自己开麦。采集、保活、播放路由保持现有调用点。
耳机麦 / 手机麦 PCM
│ 16 kHz / 16 bit / 单声道,每 40ms 1280 字节
▼
AST(RegionMSFT)
start(源语种, "pcm_s16le", 16000)
use_tts = true
target_lang = 目标语种
tts_target_lang = 目标语种
tts_speaker = 该目标语种的默认发音人
│
├─ resType=asr / trans → 原文、译文上屏(流式,不再发翻译请求)
└─ resType=tts → ttsResult.audio 交给现有 PcmStreamPlayer
iOS:
AST *ast = [[AST alloc] initWithregion:RegionMSFT delegate:self];
[ast addStringParam:@"target_lang" value:@"en"];
[ast addBoolParam:@"use_tts" value:YES];
[ast addStringParam:@"tts_target_lang" value:@"en"];
[ast addStringParam:@"tts_speaker" value:@"JennyNeural"];
[ast start:@"ja" audioEncoding:@"pcm_s16le" sampleRate:16000 userInfo:tag];
安卓用同一个机房枚举和同一组参数名。这条端到端会话的 tts_speaker 用第 9.6 节的短名(JennyNeural)。en-US-JennyNeural 是拼接路径里 OnlineTTS 的写法,不要填进 AST。
方向固定为用户选的源 → 目标。不要用识别回来的语种对调方向。
停的顺序不变:先停推流和 AST.stop(NO),再关耳机麦,再放保活。
语种和音色
源语种、目标语种都必须在下表里。默认发音人取该行的第一个;同行其余名字是可换的音色,换的时候整段会话重开,不要在 write 过程中改 tts_speaker。
界面短码和表里的 language 一致的直接用。应用里的 zh 不要写成 cn 再送进微软会话:微软这张表没有中文。
| 语种 | language | 默认发音人 | 还可选 |
|---|---|---|---|
| 阿拉伯语 | ar | AbdullahNeural | AliNeural、AmalNeural、AmanyNeural、AminaNeural、AyshaNeural、BasselNeural、FahedNeural、FatimaNeural、HamdanNeural、HamedNeural、HediNeural、ImanNeural、IsmaelNeural、JamalNeural、LailaNeural、LaithNeural、LaylaNeural、MaryamNeural、MoazNeural、MounaNeural、NouraNeural、OmarNeural、RamiNeural、RanaNeural、ReemNeural、SalehNeural、SalmaNeural、SanaNeural、ShakirNeural、TaimNeural、ZariyahNeural |
| 保加利亚语 | bg | BorislavNeural | KalinaNeural |
| 孟加拉语 | bn | BashkarNeural | NabanitaNeural、PradeepNeural、TanishaaNeural |
| 加泰罗尼亚语 | ca | AlbaNeural | EnricNeural、JoanaNeural |
| 捷克语 | cs | AntoninNeural | VlastaNeural |
| 丹麦语 | da | ChristelNeural | JeppeNeural |
| 德语 | de | AmalaNeural | BerndNeural、ChristophNeural、ConradNeural、ElkeNeural、GiselaNeural、IngridNeural、JanNeural、JonasNeural、KasperNeural、KatjaNeural、KillianNeural、KlarissaNeural、KlausNeural、LeniNeural、LouisaNeural、MajaNeural、RalfNeural、TanjaNeural |
| 希腊语 | el | AthinaNeural | NestorasNeural |
| 英语 | en | JennyNeural | GuyNeural、AriaNeural、DavisNeural、JaneNeural、JasonNeural、NancyNeural、TonyNeural、WayneNeural、WilliamNeural、RyanNeural、SoniaNeural、LibbyNeural、NatashaNeural、ClaraNeural、LiamNeural、NeerjaNeural、PrabhatNeural、LunaNeural |
| 西班牙语 | es | ElviraNeural | AlvaroNeural、AbrilNeural、ArnauNeural、DarioNeural、ElenaNeural、TomasNeural、DaliaNeural、JorgeNeural、PalomaNeural、AlonsoNeural |
| 爱沙尼亚语 | et | AnuNeural | KertNeural |
| 波斯语 | fa | DilaraNeural | FaridNeural |
| 芬兰语 | fi | HarriNeural | NooraNeural、SelmaNeural |
| 法语 | fr | DeniseNeural | HenriNeural、AlainNeural、BrigitteNeural、ClaudeNeural、SylvieNeural、JeanNeural、AntoineNeural |
| 印地语 | hi | MadhurNeural | SwaraNeural |
| 匈牙利语 | hu | NoemiNeural | TamasNeural |
| 印尼语 | id | ArdiNeural | GadisNeural |
| 意大利语 | it | ElsaNeural | IsabellaNeural、DiegoNeural、BenignoNeural、FabiolaNeural、GianniNeural |
| 日语 | ja | NanamiNeural | KeitaNeural、AoiNeural、DaichiNeural、MayuNeural、NaokiNeural、ShioriNeural |
| 韩语 | ko | SunHiNeural | InJoonNeural、BongJinNeural、HyunsuNeural、JiMinNeural、SeoHyeonNeural |
| 立陶宛语 | lt | LeonasNeural | OnaNeural |
| 拉脱维亚语 | lv | EveritaNeural | NilsNeural |
| 马来语 | ms | OsmanNeural | YasminNeural |
| 荷兰语 | nl | ArnaudNeural | ColetteNeural、FennaNeural、MaartenNeural |
| 波兰语 | pl | AgnieszkaNeural | MarekNeural、ZofiaNeural |
| 葡萄牙语 | pt | AntonioNeural | BrendaNeural、DuarteNeural、FranciscaNeural、RaquelNeural、YaraNeural |
| 罗马尼亚语 | ro | AlinaNeural | EmilNeural |
| 俄语 | ru | DariyaNeural | DmitryNeural、SvetlanaNeural |
| 斯洛伐克语 | sk | LukasNeural | ViktoriaNeural |
| 斯洛文尼亚语 | sl | PetraNeural | RokNeural |
| 瑞典语 | sv | HilleviNeural | MattiasNeural、SofieNeural |
| 斯瓦希里语 | sw | DaudiNeural | RafikiNeural、RehemaNeural、ZuriNeural |
| 泰米尔语 | ta | AnbuNeural | KaniNeural、KumarNeural、PallaviNeural |
| 泰语 | th | AcharaNeural | NiwatNeural、PremwadeeNeural |
| 土耳其语 | tr | AhmetNeural | EmelNeural |
| 乌克兰语 | uk | OstapNeural | PolinaNeural |
| 乌尔都语 | ur | AsadNeural | GulNeural、SalmanNeural、UzmaNeural |
| 越南语 | vi | HoaiMyNeural | NamMinhNeural |
文档没有给这些发音人标性别。默认列只是每行的第一个名字,用来保证换语言就换音色。
中文、粤语、爱尔兰语:拼接,但识别走微软
微软同传表没有这三语。源或目标有其中一种时,不启 AST,改成三段:
耳机麦 / 手机麦 PCM
▼
RTASR(RegionMSFT) 只识别源语种
lang = "msft" 固定值,不要把 zh-CN 填进 lang
accent = "mandarin" 固定值
domain = "ist_mul_msft" 固定值
language_name = 下表 真正的语种
▼
整句文本翻译 不再次开识别
▼
OnlineTTS(RegionMSFT) 按目标语种选微软神经音色
▼
现有 PcmStreamPlayer
安卓文档的写法:
mRTASR.lang("msft");
mRTASR.OstAccent("mandarin");
mRTASR.OstDomain("ist_mul_msft");
mRTASR.setParams("language_name", "zh-CN");
iOS 同样用 RTASR(region: RegionMSFT),language_name 用下表。现在插件把界面语种直接写进 engine.lang,和上面的固定值不符,拼接落地时要改过来。
识别语种和这条路径的默认音色:
| 界面语种 | 识别 language_name |
作为译文时的默认音色 |
|---|---|---|
普通话 zh |
zh-CN |
zh-CN-XiaoxiaoNeural |
粤语简体 yue |
yue-CN |
yue-CN-XiaoMinNeural |
粤语繁体 / 香港 zh-HK |
zh-HK |
zh-HK-HiuMaanNeural |
爱尔兰语 ga |
ga-IE |
ga-IE-OrlaNeural |
另一端如果是微软同传表里的语言,识别用该语言的区域码(英语 en-US、日语 ja-JP),合成用 OnlineTTS 的区域码音色(英语 en-US-JennyNeural,对应同传表里的 JennyNeural)。不要用星火的 x_John、x_Catherine、xiaoyan。
现在同声的 startListen 在非爱尔兰语时走进 ASR(),language=zh_cn、domain=iat。那是星火听写。中文、粤语、爱尔兰语的拼接不准再进这个分支。
翻译是整句文本,方向仍固定为源 → 目标。中间结果只上屏,整句再翻译、再合成。
两端都不在微软同传表里、又不是中文、粤语、爱尔兰语:同声不启动,也不退回星火听写。
改哪些地方
| 位置 | 改动 |
|---|---|
sparkchain 插件 iOS / Android |
同传表内:新增 AST(RegionMSFT),use_tts 和 tts_speaker 按上一节。表外三语:RTASR 按上面的四个固定参数加 language_name 启动;OnlineTTS(RegionMSFT) 用微软神经音色。同声路径不再创建 ASR,不再走 ClassicTts |
sparkchain_session.dart |
同声按语种对选一条:startAst 或 startMsftListen。startListen 里现在的星火 ASR 不给同声用 |
translation_controller.dart 同声分支 |
表内:PCM 写入 AST,译文用 trans,音频用 tts。表外三语:PCM 写入微软 RTASR,整句再翻译,再用 OnlineTTS 播目标语种。播放仍进现在的 PcmStreamPlayer |
| 发音人 | 表内用同传短名;拼接用上表的 xx-XX-NameNeural。不要读 getIflytekTTSLanguageSpecs |
SparkChain.init 的 apiType 仍按现有配置。RegionMSFT 是这一次会话的机房,不要为了同声把全局节点改掉。
验收
- 日语 → 英语:一条
AST,tts_speaker=JennyNeural。没有ASR,没有xiaoyan/tts-api.xfyun.cn。 - 英语 → 日语:
tts_speaker=NanamiNeural。两种方向的声音不同。 - 中文 → 英语:日志是
RTASR、language_name=zh-CN、lang=msft。译文用en-US-JennyNeural。没有ASR、没有zh_cn、没有晓燕。 - 英语 → 中文:识别
language_name=en-US,播报zh-CN-XiaoxiaoNeural。 - 中文 → 爱尔兰语:识别
zh-CN,播报ga-IE-OrlaNeural。 - 粤语 → 英语:识别
yue-CN或zh-HK,对上用户选的简体或香港繁体。 - 连耳机时收音日志仍是「同声翻译收音:耳机麦」,译文从耳机出。