AIVoice 概述
支持的芯片
概述
AIVoice 是一套由 Realtek 自主研发的离线 AI 解决方案,包含声学信号处理、唤醒、端点检测、识别等本地算法模块,可用于在 Realtek Ameba SoC 上搭建智能语音相关应用。
AIVoice 可以作为纯离线方案单独使用,也可以结合语音识别、大语言模型等云端系统实现一个离、在线混合的语音交互方案。
应用
应用方案
纯离线:AIVoice 单独使用,支持本地唤醒、识别等功能。
离在线:AIVoice 配合语音识别、大语言模型等云端系统使用,在本地唤醒后与云端语音交互。
应用产品
智能家居:如小爱音箱、天猫精灵等智能音箱,或智能语音家电。可通过语音控制灯光、温度和其他设备。
智能玩具:如 AI 故事机、教育机器人、陪伴机器人等。可通过语音与用户自然对话,回答十万个为什么、讲故事或进行双语教学。
车载系统:通过语音指令导航、拨打电话和播放音乐等,确保驾驶安全并提升驾驶体验。
穿戴产品:如智能手表、智能耳机和健康监测设备等。可以通过语音指令查看和发送消息、控制音乐播放器、接听电话等。
会议场景:实时转录会议内容,帮助与会者更好地记录和回顾讨论要点。
模块
模块 |
功能 |
---|---|
AFE(信号处理) |
增强语音信号、降噪,包含子模块: 回声消除、波束成形、噪声抑制、自动增益控制、声源定位 |
KWS(唤醒词检测) |
检测唤醒词以激活语音助手,如 |
VAD(语音端点检测) |
检测音频中的语音段或噪声段 |
ASR(语音识别) |
检测离线语音控制命令 |
流程
为了方便用户开发,部分算法流程已在 AIVoice 中实现:
Full Flow:一个完整的离线流程,包括 AFE、KWS 和 ASR。AFE 和 KWS 始终开启,当 KWS 检测到唤醒词时,ASR 开启并支持持续识别,超时后 ASR 退出。
AFE+KWS:离线流程包括 AFE 和 KWS,始终开启。
AFE+KWS+VAD:离线流程包括 AFE、KWS 和 VAD。AFE 和 KWS 始终开启,当 KWS 检测到唤醒词时,VAD 开启并支持持续检测语音端点,超时后 VAD 退出。
文件路径
芯片 |
操作系统 |
aivoice_lib_dir |
aivoice_example_dir |
---|---|---|---|
RTL8730E |
Linux |
{LINUXSDK}/apps/aivoice |
{LINUXSDK}/apps/aivoice/example |
RTL8721Dx/RTL8730E |
FreeRTOS |
{RTOSSDK}/component/aivoice |
{RTOSSDK}/component/example/aivoice |
RTL8713E/RTL8726E |
FreeRTOS |
{DSPSDK}/lib/aivoice |
{DSPSDK}/example/aivoice |
接口
流程和模块接口
接口 |
流程/模块 |
---|---|
aivoice_iface_full_flow_v1 |
AFE+KWS+ASR |
aivoice_iface_afe_kws_v1 |
AFE+KWS |
aivoice_iface_afe_kws_vad_v1 |
AFE+KWS+VAD |
aivoice_iface_afe_v1 |
AFE |
aivoice_iface_vad_v1 |
VAD |
aivoice_iface_kws_v1 |
KWS |
aivoice_iface_asr_v1 |
ASR |
所有接口均支持以下函数:
create()
destroy()
reset()
feed()
详情请参考 ${aivoice_lib_dir}/include/aivoice_interface.h
。
事件及回调信息
aivoice输出事件 |
事件触发时间 |
回调信息 |
---|---|---|
AIVOICE_EVOUT_VAD |
当VAD检测到语音段开始或结束 |
包含VAD状态,偏移的结构体 |
AIVOICE_EVOUT_WAKEUP |
当KWS检测到唤醒词 |
包含ID,唤醒词,唤醒得分的JSON字符串。示例: {"id":2,"keyword":"ni-hao-xiao-qiang","score":0.9} |
AIVOICE_EVOUT_ASR_RESULT |
当ASR检测到命令词 |
包含FST类型,命令词,ID的JSON字符串。 示例: {"type":0,"commands":[{"rec":"打开空调","id":14}]} |
AIVOICE_EVOUT_AFE |
AFE收到输入的每一帧 |
包含AFE输出数据,通道数等的结构体 |
AIVOICE_EVOUT_ASR_REC_TIMEOUT |
ASR/VAD超时 |
NULL |
AFE 事件定义
struct aivoice_evout_afe {
int ch_num; /* 输出音频信号的通道数,默认值:1 */
short* data; /* 增强后的音频信号 */
char* out_others_json; /* 保留用于其他输出数据(例如标志位),key: value 形式 */
};
VAD 事件定义
struct aivoice_evout_vad {
int status; /* 0: VAD 从语音变为静音,表示语音段的结束点
1: VAD 从静音变为语音,表示语音段的起始点 */
unsigned int offset_ms; /* 相对于重置点的时间偏移量 */
};
通用配置
AIVoice 可配参数:
- no_cmd_timeout:
在 full flow 中,如果在此持续时间内未检测到命令词,则 ASR 退出。在 AFE+KWS+VAD 流程中,唤醒后 VAD 仅在此持续时间内工作。
- memory_alloc_mode:
默认使用 SDK 默认堆。SRAM 模式使用 SDK 默认堆,同时还从 SRAM 分配空间用于内存关键数据。 SRAM 模式目前仅适用于 RTL8713E 和 RTL8726E DSP。
详情请参考 ${aivoice_lib_dir}/include/aivoice_sdk_config.h
。
示例
AIVoice 离线示例:使用预录音频运行全流程
该例子通过一条提前录制的三通道音频演示如何使用 AIVoice 的全流程,在开发板启动后仅运行一次。 未整合录音、播放等音频功能。
示例代码在 ${aivoice_example_dir}/full_flow_offline
目录下。
AIVoice 使用步骤
选择需要的 aivoice 流程或模块。
/* 步骤 1: * 选择需要的 aivoice 流程. * 参考 aivoice_interface.h 文件末尾查看支持的流程 */ const struct rtk_aivoice_iface *aivoice = &aivoice_iface_full_flow_v1;
准备配置参数。
/* 步骤 2: * 按需修改默认配置。 * 您可以修改 afe/vad/kws/...的 0 个或多个配置项 */ struct aivoice_config config; memset(&config, 0, sizeof(config)); /* * 这里使用 afe_res_2mic50mm 作为示例。 * 可以根据实际使用的 afe 资源修改这些配置。 * 详情请参考 aivoce_afe_config.h; * * afe_config.mic_array 必须与您链接的 afe 资源匹配 */ struct afe_config afe_param = AFE_CONFIG_ASR_DEFAULT_2MIC50MM; // 根据链接的 afe 资源修改此项 config.afe = &afe_param; /* * 仅在完全理解参数含义时修改这些设置。 * 如果不了解这些参数的含义, * 建议使用默认配置 */ struct vad_config vad_param = VAD_CONFIG_DEFAULT(); vad_param.left_margin = 300; // 可根据需要修改配置 config.vad = &vad_param; // 可设置为 NULL struct kws_config kws_param = KWS_CONFIG_DEFAULT(); config.kws = &kws_param; // 可设置为 NULL struct asr_config asr_param = ASR_CONFIG_DEFAULT(); config.asr = &asr_param; // 可设置为 NULL struct aivoice_sdk_config aivoice_param = AIVOICE_SDK_CONFIG_DEFAULT(); aivoice_param.no_cmd_timeout = 10; config.common = &aivoice_param; // 可设置为 NULL
使用
create()
和指定配置来创建并初始化 aivoice 实例。/* 步骤 3: * 创建 aivoice 实例 */ void *handle = aivoice->create(&config); if (!handle) { return; }
注册回调函数。
/* 步骤 4: * 注册一个回调函数。 * 在本示例中,您可能只会接收到部分 aivoice_out_event_type 事件类型, * 具体取决于您使用的流程。 * */ rtk_aivoice_register_callback(handle, aivoice_callback_process, NULL);
回调函数可以按实际使用需求进行修改:
static int aivoice_callback_process(void *userdata, enum aivoice_out_event_type event_type, const void *msg, int len) { (void)userdata; struct aivoice_evout_vad *vad_out; struct aivoice_evout_afe *afe_out; switch (event_type) { case AIVOICE_EVOUT_VAD: vad_out = (struct aivoice_evout_vad *)msg; printf("[user] vad. status = %d, offset = %d\n", vad_out->status, vad_out->offset_ms); break; case AIVOICE_EVOUT_WAKEUP: printf("[user] wakeup. %.*s\n", len, (char *)msg); break; case AIVOICE_EVOUT_ASR_RESULT: printf("[user] asr. %.*s\n", len, (char *)msg); break; case AIVOICE_EVOUT_ASR_REC_TIMEOUT: printf("[user] asr timeout\n"); break; case AIVOICE_EVOUT_AFE: afe_out = (struct aivoice_evout_afe *)msg; // afe 每帧都会输出音频 // 本示例中,为了让日志清晰仅打印一次 static int afe_out_printed = false; if (!afe_out_printed) { afe_out_printed = true; printf("[user] afe output %d channels raw audio, others: %s\n", afe_out->ch_num, afe_out->out_others_json ? afe_out->out_others_json : "null"); } // 按需处理 afe 输出的音频 break; default: break; } return 0; }
使用
feed()
给 aivoice 输入音频数据。/* 在芯片上运行时,通常使用麦克风采集的实时音频流, * 本示例中使用一条固定音频 * */ const char *audio = (const char *)get_test_wav(); int len = get_test_wav_len(); int audio_offset = 44; int mics_num = 2; int afe_frame_bytes = (mics_num + afe_param.ref_num) * afe_param.frame_size * sizeof(short); while (audio_offset <= len - afe_frame_bytes) { /* step 5: * Feed the audio to the aivoice instance. * */ aivoice->feed(handle, (char *)audio + audio_offset, afe_frame_bytes); audio_offset += afe_frame_bytes; }
(可选) 如果需要重置状态,使用
reset()
。如果不再需要 aivoice,使用
destroy()
销毁实例。/* 步骤 6: * 销毁 aivoice 实例 */ aivoice->destroy(handle);
编译示例
切换到 SDK 的 GCC 项目目录
cd {SDK}/amebadplus_gcc_project
运行
menuconfig.py
进入配置界面./menuconfig.py
导航至以下菜单路径开启 TFLM 库和 AIVoice
--------MENUCONFIG FOR General--------- CONFIG TrustZone ---> ... CONFIG APPLICATION ---> GUI Config ---> ... AI Config ---> [*] Enable TFLITE MICRO [*] Enable AIVoice
编译固件
./build.py -a full_flow_offline
编译 DSP 的 TFLM 库, 请参考 编译 TFLM。
也可使用{DSPSDK}/lib/aivoice/prebuilts 目录下预编译好的 TFLM 库。
在 Xtensa Xplorer 中导入
{DSPSDK}/example/aivoice/full_flow_offline
源。进行软件相关配置,按需修改链接的库如 AFE 资源、KWS 资源等。
添加包含路径(-I)
${workspace_loc}/../lib/aivoice/include
添加库搜索路径(-L)
${workspace_loc}/../lib/aivoice/prebuilts/$(TARGET_CONFIG) ${workspace_loc}/../lib/xa_nnlib/v1.8.1/bin/$(TARGET_CONFIG)/Release ${workspace_loc}/../lib/lib_hifi5/project/hifi5_library/bin/$(TARGET_CONFIG)/Release ${workspace_loc}/../lib/tflite_micro/project/bin/$(TARGET_CONFIG)/Release
添加库(-l)
-laivoice -lafe_kernel -lafe_res_2mic50mm -lkernel -lvad -lkws -lasr -lfst -lcJSON -ltomlc99 -ltflite_micro -lxa_nnlib -lhifi5_dsp
编译固件,请参考 DSP 编译 中的步骤。
编译 DSP 的 TFLM 库, 请参考 编译 TFLM。
也可使用{DSPSDK}/lib/aivoice/prebuilts 目录下预编译好的 TFLM 库。
在 Xtensa Xplorer 中导入
{DSPSDK}/example/aivoice/full_flow_offline
源。进行软件相关配置,按需修改链接的库如 AFE 资源、KWS 资源等。
添加包含路径(-I)
${workspace_loc}/../lib/aivoice/include
添加库搜索路径(-L)
${workspace_loc}/../lib/aivoice/prebuilts/$(TARGET_CONFIG) ${workspace_loc}/../lib/xa_nnlib/v1.8.1/bin/$(TARGET_CONFIG)/Release ${workspace_loc}/../lib/lib_hifi5/project/hifi5_library/bin/$(TARGET_CONFIG)/Release ${workspace_loc}/../lib/tflite_micro/project/bin/$(TARGET_CONFIG)/Release
添加库(-l)
-laivoice -lafe_kernel -lafe_res_2mic50mm -lkernel -lvad -lkws -lasr -lfst -lcJSON -ltomlc99 -ltflite_micro -lxa_nnlib -lhifi5_dsp
编译固件,请参考 DSP 编译 中的步骤。
FreeRTOS
切换到 SDK 的 GCC 项目目录
cd {SDK}/amebasmart_gcc_project
运行
menuconfig.py
进入配置界面./menuconfig.py
导航至以下菜单路径开启 TFLM 库和 AIVoice
--------MENUCONFIG FOR General--------- CONFIG TrustZone ---> ... CONFIG APPLICATION ---> GUI Config ---> ... AI Config ---> [*] Enable TFLITE MICRO [*] Enable AIVoice
根据硬件选择相应的 AFE 资源,默认
afe_res_2mic50mm
AI Config ---> [*] Enable TFLITE MICRO [*] Enable AIVoice Select AFE Resource ( ) afe_res_1mic ( ) afe_res_2mic30mm (X) afe_res_2mic50mm ( ) afe_res_2mic70mm
选择 KWS 资源,默认固定唤醒词
小强小强
、你好小强
AI Config ---> [*] Enable TFLITE MICRO [*] Enable AIVoice Select AFE Resource Select KWS Resource (X) kws_res_xqxq ( ) kws_res_custom
编译固件
./build.py -a full_flow_offline
Linux
(可选) 如果需要更换 AFE 资源或 KWS 资源,修改 yocto recipe
{LINUXSDK}/yocto/meta-realtek/meta-sdk/recipes-rtk/aivoice/rtk-aivoice-algo.bb
里的库。通过 bitbake 编译 aivoice 可执行文件:
bitbake rtk-aivoice-algo
预期结果
在开发板上烧录固件,运行后,日志会打印算法结果如下:
[AIVOICE] set multi kws mode
---------------------SPEECH COMMANDS---------------------
Command ID1, 打开空调
Command ID2, 关闭空调
Command ID3, 制冷模式
Command ID4, 制热模式
Command ID5, 加热模式
Command ID6, 送风模式
Command ID7, 除湿模式
Command ID8, 调到十六度
Command ID9, 调到十七度
Command ID10, 调到十八度
Command ID11, 调到十九度
Command ID12, 调到二十度
Command ID13, 调到二十一度
Command ID14, 调到二十二度
Command ID15, 调到二十三度
Command ID16, 调到二十四度
Command ID17, 调到二十五度
Command ID18, 调到二十六度
Command ID19, 调到二十七度
Command ID20, 调到二十八度
Command ID21, 调到二十九度
Command ID22, 调到三十度
Command ID23, 开高一度
Command ID24, 开低一度
Command ID25, 高速风
Command ID26, 中速风
Command ID27, 低速风
Command ID28, 增大风速
Command ID29, 减小风速
Command ID30, 自动风
Command ID31, 最大风量
Command ID32, 中等风量
Command ID33, 最小风量
Command ID34, 自动风量
Command ID35, 左右摆风
Command ID36, 上下摆风
Command ID37, 播放音乐
Command ID38, 暂停播放
Command ID39, 接听电话
Command ID40, 挂断电话
---------------------------------------------------------
[AIVOICE] rtk_aivoice version: v1.5.0#S0825120#N1ed33d6#A6c25e38
[AIVOICE] rtk_aivoice_model afe version: afe_2mic_asr_v1.3.1_AfePara_2mic50_v2.0_bf_v0.0_20250401
[AIVOICE] rtk_aivoice_model vad version: vad_v7_opt
[AIVOICE] rtk_aivoice_model kws version: kws_xqxq_v4.1_opt
[AIVOICE] rtk_aivoice_model asr version: asr_cn_v8_opt
[AIVOICE] rtk_aivoice_log_format version: v2
[user] afe output 1 channels raw audio, others: {"abnormal_flag":0,"ssl_angle":-10}
[AIVOICE] [KWS] result: {"id":2,"keyword":"ni-hao-xiao-qiang","score":0.7746397852897644}
[user] wakeup. {"id":2,"keyword":"ni-hao-xiao-qiang","score":0.7746397852897644}
[user] voice angle 90.0
[user] vad. status = 1, offset = 385
[user] vad. status = 0, offset = 1865
[AIVOICE] [ASR] result: {"type":0,"commands":[{"rec":"打开空调","id":1}]}
[user] asr. {"type":0,"commands":[{"rec":"打开空调","id":1}]}
[user] voice angle 90.0
[user] vad. status = 1, offset = 525
[AIVOICE] [KWS] result: {"id":2,"keyword":"ni-hao-xiao-qiang","score":0.750707507133484}
[user] wakeup. {"id":2,"keyword":"ni-hao-xiao-qiang","score":0.750707507133484}
[user] voice angle 90.0
[user] vad. status = 1, offset = 445
[user] vad. status = 0, offset = 1765
[AIVOICE] [ASR] result: {"type":0,"commands":[{"rec":"播放音乐","id":37}]}
[user] asr. {"type":0,"commands":[{"rec":"播放音乐","id":37}]}
[user] voice angle 90.0
术语
- AEC
AEC (Acoustic Echo Cancellation),声学回声消除,或回声消除,是指消除输入信号中的回声信号。回声信号是指麦克风采集到的设备自身扬声器播放的音频。
- AFE
AFE (Audio Front End),音频前端,或信号处理,是指用于原始音频信号预处理的一些模块的组合。通常在进行语音交互前执行以增强信号质量,包含多种语音增强算法。
- AGC
AGC (Automatic Gain Control),自动增益控制,用于动态调节信号的增益,自动调整信号幅值,以保持最佳信号强度。
- ASR
ASR (Automatic Speech Recognition),语音识别,是指把音频中的语音识别为文本。它可用于搭建语音用户界面,实现人类与人工智能设备的语音交互。
- BF
BF (BeamForming),波束形成,是指一种为麦克风阵列设计的空间滤波器,用于增强来自特定方向的信号同时衰减其他方向的信号。
- KWS
KWS (Keyword Spotting),关键词检测,或唤醒词检测、语音唤醒,是指从音频中识别特定的唤醒词。通常是语音交互的第一步,设备检测到唤醒词后,会进入等待语音指令状态。
- NN
NN (Neural Network),神经网络,是一种用于人工智能各类任务的机器学习模型。神经网络依靠训练数据学习并提升准确性。
- NS
NS (Noise Suppression),噪声抑制,或降噪,是指抑制信号中的环境噪声以增强语音信号,尤其是稳态噪声。
- RES
RES (Residual Echo Suppression),残余回声抑制,是指抑制 AEC 处理后的残余回声信号。是 AEC 的后置滤波器。
- SSL
SSL (Sound Source Localization),声源定位,是指利用麦克风阵列估计声源的空间方位。
- TTS
TTS (Text-To-Speech),语音合成,是一种将文本转换为语音的技术。它可用于各种需要将文本转换为人声的语音应用中。
- VAD
VAD (Voice Activity Detection),语音活性检测,或语音端点检测,是指从音频中检测有无语音信号。它被广泛用于语音增强、语音识别等系统中,也可用于去除音频会话中的非语音片段以减少计算、带宽等。