ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于杰理音频SoC的同声翻译设备开发实战

基于杰理音频SoC的同声翻译设备开发实战

杰理之同声翻译【篇】

做智能硬件的人应该都有感觉,这两年“同声翻译”这件事被普通消费者盯得越来越紧。大家出去旅个游、开个跨国的线上会议,掏出一个小设备就能让两个语言完全不通的人顺畅聊天,这种需求真实存在,而且终端产品的形态已经从手机App延伸到翻译笔、翻译耳机、翻译对讲机。我最近用杰理方案完整跑了一版同声翻译原型机,从麦克风采集到云端翻译再回到本地播放,把整条链路从头到尾调了一遍,踩了不少坑,也有一些值得分享的收获。

这篇东西不是产品发布会通稿,就是一个开发者的实操记录。重点放在:为什么这种产品形态适合用杰理这类音频SoC来做,端侧和云端该怎么分工,VAD断句和降噪到底怎么调才不翻车,以及真实使用中遇到的延迟、断句、弱网等问题怎么排查。如果你正打算做翻译类硬件,或者手里已经拿了杰理开发板但不知道从哪里下手,这篇可以当一份参考地图用。

1. 方案选型:为什么翻译类硬件,杰理这颗芯够用

先说结论:同声翻译设备本质上不是一个“算力密集型”产品,它是一个“音频链路+网络链路”必须同时打通的低功耗嵌入式设备。搞清楚这个定位,选型逻辑就清楚了大半。

1.1 同声翻译设备的真实需求拆解

一台翻译机的完整工作流看起来很简单:用户说一段话,机器把声音传出去,拿回一段翻译结果,再念给对面听。但拆开看,这里有四条硬性要求。

第一是音频采集质量。双麦或者多麦阵列几乎是标配,因为公开场合噪声不可控。第二是低延迟数据通路,用户说完话到翻译结果播放出来,这个时间如果超过3秒,体验就会变成“我说完了,机器还在发呆”,所以全链路必须是准实时的。第三是低功耗连续待机,手持设备不可能让用户频繁充电。第四是成本可控,这类产品往往是量产走量的逻辑,核心器件价格压不下来,整个产品就没有竞争力。

把这些需求放到一起,你会发现手机应用处理器方案是过配的:性能强但外设电路复杂、功耗高、BOM成本高。而一颗普通MCU又不够用,因为音频编解码和网络协议栈同时跑起来之后,资源没法平衡。杰理这类音频SoC卡在中间正好合适:它本身有比较完整的音频硬件编解码通路,麦克风阵列接口是现成的,蓝牙和WiFi模块也可以灵活搭配,SDK里对音频处理的支持比通用MCU完善得多。

1.2 杰理方案最讨喜的三个点

不是说杰理没有缺点,但它在翻译设备这个场景里,有三个优点非常突出。

第一个是音频硬件链路完整。录音通路和播放通路都被封装好了,底层驱动基本不用从头写,你可以把精力放在上层业务逻辑,而不是天天跟I2C时序和DMA中断搏斗。第二个是低功耗状态下能做到秒级唤醒。翻译机大部分时间处于待机,用户拿起来按键说一句话,设备能马上进入工作状态,这个响应速度直接影响使用体验,杰理这套电源管理方案实测表现可以。第三个是量产烧录和SDK资料成熟。做硬件的都知道,方案资料全不全、量产工具顺不顺,很多时候比芯片本身性能更重要,杰理在这一块的配套确实省心。

1.3 和其他方案放在一起看

我拿同类的国产音频SoC和低端应用处理器做过对比。如果用应用处理器方案,好处是跑Linux/RTOS都很从容,甚至可以本地塞一个小模型做离线翻译,但代价是硬件设计复杂度上来了,DDR和eMMC这些外围都跑不掉,四层板变六层,功耗也压不下去。如果用纯MCU,你会发现最基础的AAC编解码都要靠软解,CPU直接被打满,更别谈网络协议栈和UI交互。

杰理是中间态:音频硬件处理交给专用通路,网络协议栈占用的算力可控,UI层用轻量级方案就够了。最后你得到的是一块面积小、功耗低、电池能撑住的板子,这对于手持翻译类产品来说,比单纯堆性能更有价值。

提示:选型时别只看芯片本身,要算外围整套BOM。翻译设备还需要一颗codec、一颗电源管理、一个网络模块,杰理的优势在于很多外围可以省掉或者复用,整体省下来的面积和成本相当可观。

2. 系统架构与翻译链路设计

方案定了之后,第二步是画整条数据流。同声翻译系统看上去只要有录音和播放就行,但实际架构上要把端侧、传输、云服务三块切干净,每一块职责单一,后面出问题才好定位。

2.1 整条链路先想清楚再动手

一条完整的翻译链路是:麦克风采集 → 前端降噪 → VAD检测 → 音频编码 → 网络上传 → 语音识别 → 机器翻译 → 语音合成 → 音频下载 → 本地解码 → 扬声器播放。

这个链路里,前四步和最后三步在端侧,中间四步在云端。端侧和云端的接口就是一段音频数据过去、一段音频数据回来。划分清楚之后,你就知道杰理芯片上要做什么了:音频采集、降噪、VAD、编码、压缩上传、下载解码、播放,外加按键交互和状态显示。至于识别、翻译、合成,全部交给云端,端侧不碰。

这么划分有一个好处:后续升级翻译引擎不需要动硬件,改云端接口配置就行。而且市面上各大语音服务商的接口形态都差不多,做到协议层解耦,随时可以换服务商,不至于被单一厂商绑死。

2.2 端侧模块划分与数据流控制

杰理侧的程序我建议按“采集线程+网络线程+播放线程”三个模块来做,中间用环形缓冲区解耦。

采集线程负责从麦克风拿数据,做降噪和VAD检测。当VAD判定用户开始说话,数据被持续写入缓冲区。网络线程从缓冲区取数据,按协议打包上传。播放线程负责接收云端返回的音频流,解码后送扬声器。

关键点在于缓冲区大小和调度优先级。采集线程必须最高优先级,否则音频会断流。我曾经把网络上传放在一个轮询任务里,结果WiFi握手的时候采集线程被抢占,录音出现明显卡顿,后来把所有音频相关的处理统一挂到中断或者高优先级任务里才解决。缓冲区建议给到300到500毫秒的量,既能吸收网络抖动,又不会让延迟失控。

2.3 云侧对接与协议设计

云端接口设计,核心决策是短连接还是长连接。

很多新手第一版都做成HTTP短连接:按一下录音,录完一整段发过去,然后等返回。好处是简单,但致命问题是“录完一整段”这个动作让用户等太久。人说话天然是连续不断的一段一段,如果非要等一个完整句子结束才上传,你会面临一个很尴尬的问题:怎么定义句子结束?靠静音?静音多久算断句?

我的建议直接上WebSocket长连接,配合流式上传。用户的音频数据一边采集一边上传,云端识别引擎也是边收边出中间结果,整段话说完后大概几百毫秒就能拿到完整翻译结果。实测下来这个方案配合流式语音识别,可以做到用户话音刚落一两秒内开始播放翻译语音,体验完全不一样。

协议格式上,我推荐用轻量的JSON,字段就几个:设备ID、语言对、音频格式、序列号。需要注意音频编码格式要和云端识别服务对齐,一般16kHz单声道PCM最通用,也可以做一层OPUS压缩省流量,但后端要能解。

注意:长连接一定要设计心跳机制,不然设备待机一段时间后,云端会因为连接空闲把链接断开,你下次发送才发现socket已经死了,又是一轮重连延迟。心跳间隔建议在30秒左右,同时做好断线自动重连的补偿逻辑。

3. 核心环节实现与参数配置

架构清楚了,剩下的全是细节。这一章是我认为整篇最值钱的部分:VAD断句、降噪处理、延迟优化、TTS回放,每一个单独拎出来都是能直接影响体验的坎。

3.1 VAD断句参数:静音多久才算一句话说完

VAD是整个链路里最容易被低估的模块。VAD判断不好,翻译出来的东西就是碎的或者糊的。

先说基本原理。VAD就是检测一段声音里“有人说话”和“没人说话”的边界。常用的特征有两个:短时能量和过零率。短时能量可以区分语音和静音,但噪声环境下容易误判,需要过零率辅助判断是不是真正的人声。杰理SDK里有现成的VAD接口,但默认参数是按普通对讲机场景调的,用在翻译设备上必须自己重新标定。

我实测下来几个关键参数如下,你可以当初始值用,再根据产品场景细调:

  • 音频帧长:10ms到20ms,对应16kHz采样率,也就是160到320个采样点。
  • 语音起始阈值:短时能量连续3帧超过设定值,判定进入语音状态。
  • 语音结束条件:连续25到40帧都是静音,判定一句话结束。按16kHz、20ms每帧算,25帧就是500毫秒静音。
  • 最长语音包:如果用户在10秒内没有任何停顿,强制截断并上传,防止网络请求无限等待。

这里有个很关键的经验:静音结束阈值不要低于450毫秒。我之前图省事,设成200毫秒,结果用户说话稍微慢一点,中间呼吸停顿就被当成断句,整段话被切成了好几个碎片,翻译结果完全没法看。调到500到600毫秒后,正常语速的人基本不会被误切,但代价是如果用户说话停顿特别久,反应会慢半拍,这个取舍看你产品的目标人群。

另外一定要做语音起始能量的自适应。同一个设备,在安静的卧室和嘈杂的地铁站,环境底噪完全不同。用固定阈值的结果就是:地铁上不说话也一直触发上传,卧室里说悄悄话根本录不进去。我在代码里加了一个滑动窗口,每200毫秒更新一次环境底噪估计值,语音起始阈值取底噪加一个固定增量,实测在各种环境下的稳定性明显提升。

3.2 降噪与回声消除:翻译设备最容易忽略的两个坑

同声翻译产品最常见的用户抱怨是“我说中文它翻错”,可以说一半以上的“翻错”其实是“没听清”,问题出在采集端。所以降噪处理必须重视。

硬件层面,我强烈建议用双麦克风阵列。一个主麦朝前,采集目标语音,一个副麦朝后,采集环境噪声,两颗麦的间距大概1.5到2厘米。杰理方案支持差分降噪,通过两路信号的相位差把环境噪声抵消掉,实测在70分贝左右的马路环境里,语音识别率比单麦方案高出一大截。

软件层面,谱减法是最实用的。它的原理是把带噪语音的频谱减去估计出来的噪声频谱,剩下比较干净的目标语音。缺点是会引入“音乐噪声”,就是听起来有种吱吱的电流音。解决办法是处理完以后加一个柔和的人声掩膜,只保留和中频人声重合比较多的频段,音乐噪声会轻很多。

然后是回声消除。你必须记住一个原则:翻译设备工作时,麦克风采集和扬声器播放绝对不能同时进行。原因很简单,机器把翻译结果放出来的时候,麦克风如果还在采集,扬声器声音会顺着空间传回麦克风,形成自激,云端识别到的是两段声音混在一起,翻译必然出错。

我的方案是做一个简单的播放打断机制:播放TTS之前,立刻停止采集并清空采集缓冲区。TTS播完后再恢复采集。如果你的产品形态是耳机,还要在硬件上做回声参考信号接口,把扬声器的输出信号直接引回芯片做自适应滤波,但这套复杂度更高,原型机阶段用播放时停止采集的方案最稳。

3.3 翻译延迟优化:端到端3秒是怎么挤出来的

延迟是衡量同声翻译设备体验最核心的指标。用户从说完一句话到听到翻译结果,这个耗时叫端到端延迟。我定的及格线是3秒,优秀线是2秒以内。

拆开来看,延迟由六段组成:本地VAD判定结束的等待时间、音频上传时间、云端识别耗时、机器翻译耗时、语音合成耗时、音频下载和播放启动时间。

第一段,VAD判定结束的等待时间,就是你说的静音阈值,设了500毫秒就是500毫秒,躲不掉。第二段和第六段,取决于网络环境。第三到第五段是云端服务耗时,通常在1到1.5秒之间。所以本地端能优化的主要是第一段和第六段。

优化第六段有一个很实用的技巧:提前启动播放。云端的语音合成一般都是边合成边流式返回,不是说等整段音频都合成完才给你。你可以让云端在合成出第一个音频分片后就立刻下发,端侧拿到第一片就开始播放,后面边下边播。这样到最后一段话音的时候,整个体验跟真人对话差不多,节省了大几百毫秒。这个方案叫流式TTS,实测能把端到端延迟从3.5秒压到2.4秒左右。

另外网络协议上,我建议把音频编码格式统一成OPUS。16kHz采样率下OPUS设置码率24kbps,每帧20毫秒,压缩率高而且算法延迟低,比PCM格式省流量,也省传输时间。云端侧语音识别服务商一般都支持OPUS或PCM,接口配置里选对格式就行。

3.4 TTS回放策略:语速、音量和打断逻辑

最后端侧还有一个容易被忽视的模块就是TTS播报。

云端返回的TTS音频多数是24kHz或者48kHz采样率的MP3或PCM,而杰理本地播放通路通常按44.1kHz或者48kHz输出,中间有采样率不匹配的问题。我建议统一在云端侧就把音频转码成16kHz单声道PCM下发,虽然流量大一点,但省去了端侧采样率转换的算力,而且16kHz人声频段完全够听,播放链路稳定很多。

音量设置上有一个细节:不要拉满。拉满音量会导致扬声器削顶失真,听起来破音,而且容易把周围环境音盖住,让用户听不清自己的话。实测在安静环境下音量调到60%左右听感最佳,嘈杂环境可以到80%,但超过90%基本都是反效果。

打断逻辑也要设计。用户按下停止键,或者检测到用户又开始说话,必须立即停止当前TTS播放,清空播放队列,并把网络请求取消。如果不打断,会有一个很尴尬的场景:用户在听第一段翻译的时候,第二段已经开始播了,两段声音叠在一起,体验非常糟糕。这里我推荐在播放线程里做一个原子标志位,任何新语音输入都能拉高这个标志,播放线程每个音频帧检查一次,有标志就立刻退出。

实战心得:调试延迟的时候,别凭感觉判断快慢。我在代码里加了一个日志点,每完成一个阶段就打印一次时间戳,比如“VAD结束时间戳”“首包发出时间戳”“首包收到时间戳”“开始播放时间戳”。攒了几天数据之后,哪个环节慢了,一目了然。特别是云端识别耗时,不同时段差异很大,有日志才能做针对性优化。

4. 常见问题与排查技巧实录

这一章记录我在实际调试中遇到最多的四个问题,全部有对应的定位思路和解决路径。如果你照着做,能少走不少弯路。

4.1 断句错乱:静音阈值和采样帧长不匹配

现象很典型:用户说了一个比较长的句子,中途正常停顿换气,结果设备把这句话截成了两段,翻译出来前后不通。

先从日志看VAD判定时间。如果判定结束的时间明显早于用户真正说完的时间,基本就是静音阈值太小。把静音帧数从20帧加到30帧,同时确认音频帧长和采样率之间的换算对不对。有一次我发现代码里帧长写的是30ms,但注释写的是20ms,导致实际静音判断时间只有理论值的六成,这种低级错误最容易让人绕远路。

还有一种情况是环境底噪忽高忽低,导致VAD频繁误触发或误结束。这时候就要检查底噪自适应更新算法,比如底噪估计值是否被一个突然出现的响声带偏了,导致后续所有阈值全部漂移。解决方法是把底噪更新设成慢速滑动平均,不到万不得已不要被瞬时噪声影响。

4.2 翻译延迟高:到底卡在云端还是网络

用户反馈“我说完了三秒才听到翻译”,但具体是网络慢还是云服务慢,必须靠日志分段。

我在调试时发现,如果首包上传耗时正常,但识别结果迟迟不返回,大概率是云端服务的并发能力不够,或者是方言识别导致模型推理变慢。换一个服务商测试,同样的音频数据在另一家返回速度快了一倍,问题定位到云端。

如果首包上传本身就慢,那就是上行带宽不足或者公网链路质量差。这时候检查你用的4G模块天线是否焊接良好、SIM卡是否限速、以及网络模块和杰理主控之间的串口波特率是否被恶意压低了。我试过把串口波特率从921600改成115200来省电,结果上传带宽直接砍到原来的八分之一,延迟爆炸,这种优化真的是得不偿失。

4.3 弱网环境下频繁超时:重试策略不能乱写

原型机拿到展会现场测试,人一多WiFi就瘫痪,网络请求一个接一个超时。如果你在代码里粗暴地做“失败就重试”,后果就是重试请求把本来就不堪重负的网络彻底堵死,然后系统进入雪崩状态。

我给网络模块设计了一个两级重试策略:第一级是单次请求的超时重试,最多重试一次,间隔300毫秒。如果第二次还是失败,进入第二级降级处理,直接把当前翻译请求放弃,提示用户网络异常,恢复采集状态。

为什么放弃而不是无限重试?因为同声翻译是实时交互场景,用户已经说完话了,你重试就算成功也是延迟极高,还不如让用户重新说一遍。另外,第二级降级之后,下一次翻译请求要等连接完整重建,避免在恶劣网络下继续硬碰硬。

4.4 电池续航崩了:问题可能出在TTS队列

有一版固件测出来待机功耗正常,但一进入翻译状态就疯狂掉电,半小时从满电到关机。

查了半天发现,罪魁祸首是网络模块在每次翻译结束后没有主动休眠,一直保持着全速连接状态。翻译会话结束后,网络模块应该进入低功耗模式,只保留心跳连接,有数据时再唤醒。这个逻辑我在第一版完全没做,等于用户说完一句话,设备就一直全速运行,功耗自然爆炸。

另一个隐藏耗电源是TTS播放队列。云端的流式TTS会把后续音频分片提前下发,如果端侧网络线程不及时处理,音频数据会堆积在缓冲区,设备一直处于连续接收和播放状态,每个分片之间只有几十毫秒的休息,MCU和网络模块都得不到休眠时间。解决办法是加一个播放完成通知,云端收到通知再下发后续分片,这样一段翻译结束,链条立刻安静下来。

我把这些常见问题整理成一张速查表,方便你对照排查:

异常现象可能原因优先排查项
长句被切成碎片VAD静音阈值过小调整静音帧数到25帧以上
声音断断续续采集线程被抢占提高采集任务优先级
翻译延迟飘忽不定音频编码格式不匹配统一用OPUS 16kHz格式
翻译结果胡言乱语静音检出异常或背景噪声大检查底噪自适应性,启用双麦差分
待机电流正常但工作时掉电快网络模块未休眠翻译结束后主动休眠网络模块
播放同时麦克风啸叫TTS播放和采集重叠播放前强制停止采集并清缓冲区
硬启动后第一段话老是丢长连接未就绪就发数据确认WebSocket连接建立后再允许录音

这套调试下来,我的心得是:同声翻译设备的代码量和算法难度其实都不算高,真正难的是整条链路的稳定性——每一个环节单独看都能工作,但把它们串起来一旦某个环节掉链子,用户体验就是灾难性的。所以做这类项目,我强烈建议从一开始就把日志系统和各阶段耗时统计做进去,别等到出了问题才临时加,那样你会错过很多真实的现场数据。

目前这版原型机已经能稳定跑完中英、中日、中韩这几个高频语言对的翻译,完整对话场景下端到端延迟控制在2.5秒左右,日常交流基本够用。后续我想把离线短语翻译和在线全量翻译做一套无缝切换,让设备在完全没有网络的情况下也能应急用起来,那又是另一个值得慢慢啃的方向了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进