杰理 SDK 文档中心
首页
首页
  • SDK 概述与快速开始

    • SDK 概览与 AC791N 芯片平台
    • 环境搭建与编译指南
    • 烧录与固件升级
    • 工程结构导览
  • 产品方案应用

    • WiFi 摄像头方案
    • WiFi IPC 可视对讲方案
    • WiFi 故事机方案
    • 扫码枪 HID 方案
    • 开发板示例工程
  • 公共应用组件

    • 语音识别 ASR 引擎
    • LLM 与 AI 语音助手接入
    • 摄像头传感器驱动
    • UI 显示框架与驱动
    • USB 主机与设备栈
    • 文件系统与存储管理
    • 系统服务与外设管理
    • 生产测试与射频工具
  • 蓝牙协议栈

    • 经典蓝牙 BR/EDR
    • BLE 低功耗蓝牙
    • 蓝牙 Mesh 网络
    • 蓝牙扩展协议(RCSP/广播/无线麦克风)
  • WiFi 与网络协议栈

    • WiFi 驱动与网络模式
    • lwIP TCP/IP 协议栈
    • 网络安全与加密库
    • 应用层网络协议
    • 流媒体与音视频传输
    • 云平台接入 SDK
    • P2P 远程访问与设备互联
  • 芯片平台与驱动

    • wl82 平台与硬件加速
    • 外设驱动框架
    • 平台配置与固件打包工具
  • 媒体与音频引擎

    • 音频编解码与音源
    • 音效处理引擎
    • 视频与图像处理
  • 操作系统与运行时

    • 实时操作系统与 POSIX 层
    • C/C++ 运行时库
  • 开发资源与文档

    • 文档与规格书
    • 公共示例工程
    • UI 资源工程与打包
    • SDK 辅助工具与脚本

语音识别 ASR 引擎

AC79 AIoT SDK 中的语音识别(ASR)引擎能力,涵盖 asr_server 服务任务接口、Roobo/Fig 本地识别算法 API、简洁封装层以及 Wanson、腾讯云等第三方 ASR 供应商集成。

Purpose and Scope

本页说明 AC79 系列芯片 SDK 中 ASR 引擎的完整架构与实现,包括:

  • 服务框架层:include_lib/server/asr_server.h 定义的 ASR 服务器消息/请求/事件协议,以及 app_main.c 中 asr_server 任务注册方式;
  • 本地算法层:Roobo/Fig 引擎的公开 API(fig_asr_api.h)与数据类型(fig_asr_type.h),即神经网络(NNET)+ WFST 解码器架构;
  • 简洁封装层:apps/common/asr/roobo/asr.h 提供的 asr_init / asr_process 等极简接口;
  • 第三方供应商集成:Wanson 引擎(apps/common/asr/wanson/fn_asr.h 及预编译库 lib_wanson_asr.a)与腾讯云 IoT 云端 ASR(qcloud_iot_export_asr.h)。

以下主题属于相邻页面,不在本页展开:语音唤醒(wake-on-voice / KWS)算法的内部实现、音频采集与播报链路、各应用(wifi_story_machine 等)的 ASR 业务交互逻辑。本页聚焦 ASR 引擎本身的接口、分层与运行机制。

Overview

在 AC79 这类资源受限的 AIoT 芯片上,语音识别被设计为分层、可替换的子系统,其核心设计意图有四点:

  1. 任务隔离:ASR 作为一个独立 server 任务运行(见 apps/wifi_camera/app_main.c 中 "asr_server" 任务注册,优先级 15、栈 1024),与音频采集、网络、UI 任务解耦,避免识别计算阻塞其他关键路径。
  2. 算法可替换:SDK 同时提供 Roobo/Fig 本地引擎(apps/common/asr/roobo/)与 Wanson 引擎(apps/common/asr/wanson/ 及预编译库),上层业务通过统一的服务器接口使用,切换供应商无需改动业务代码。
  3. 在线/离线双模式:本地引擎(Fig、Wanson)用于无网络或低延迟场景;腾讯云 IoT SDK 提供云端 ASR 出口,用于需要大词表或云端语义理解的场景。
  4. 实时流式处理:本地识别以 30ms(16kHz/16bit/mono 下 480 个采样点)为音频帧粒度流式送入引擎,配合唤醒(wake-on-voice)机制,实现"先唤醒、后识别"的低功耗交互链路。

理解这套机制的关键是掌握三个层次:服务框架层(server 协议)→ 算法抽象层(Fig API / 简洁封装)→ 供应商实现(预编译库 / 云端 SDK)。

Architecture

flowchart TD
    subgraph sg_App["应用层 (apps)"]
        AppMain["app_main.c<br/>server 任务注册表"]
        StoryApp["wifi_story_machine 等业务应用"]
    end

    subgraph sg_Server["服务框架层 (server)"]
        AsrServer["asr_server 任务<br/>prio=15, stack=1024, qsize=64"]
        WakeVoice["wake-on-voice 任务<br/>prio=7, stack=1024"]
        AsrProto["asr_server.h<br/>STATE / ASR_REQ / ASR_SER_EVENT"]
    end

    subgraph sg_Algo["本地算法层"]
        FigApi["Fig API (Roobo)<br/>fig_asr_api.h / fig_asr_type.h"]
        SimpleAsr["简洁封装 asr.h<br/>asr_init / asr_process"]
        Wanson["Wanson 引擎<br/>fn_asr.h + lib_wanson_asr.a"]
    end

    subgraph sg_Cloud["云端"]
        Tencent["腾讯云 IoT ASR<br/>qcloud_iot_export_asr.h"]
    end

    AppMain -->|"注册 server 任务"| AsrServer
    AsrServer --> AsrProto
    AsrServer -->|"唤醒开/关请求"| WakeVoice
    WakeVoice -->|"ASR_SER_EVENT_WAKE"| AsrServer
    AsrServer --> FigApi
    AsrServer --> SimpleAsr
    AsrServer --> Wanson
    StoryApp -->|"识别请求/结果"| AsrServer
    StoryApp -->|"云端识别"| Tencent

架构分层说明

  • 应用层:app_main.c 中的 server 任务表把 asr_server 注册为系统任务(wifi_camera、wifi_ipc 均以 {"asr_server", 15, 1024, 64} 登记,即优先级 15、栈 1024 字节、消息队列深度 64);业务应用如 wifi_story_machine 通过任务消息与 ASR 引擎交互。
  • 服务框架层:asr_server.h 定义引擎对外的最小协议面——开关状态、唤醒请求、唤醒事件,以及 struct asr_wake 携带的唤醒参数。该头文件放在 include_lib/server/ 下,说明它是被 server 框架与各应用共同引用的公共契约。
  • 本地算法层:Fig API 以不透明句柄 FIG_INST 隔离实现细节;asr.h 则是更上层的极简封装(面向"喂 30ms 音频、拿文本"的直白用法)。Wanson 引擎以预编译库形式提供,编译期通过 CONFIG_ASR_ALGORITHM 等宏选择(见 apps/wifi_story_machine/app_music_dui.c 中的条件编译引用)。
  • 云端:腾讯云 IoT C SDK 导出 qcloud_iot_export_asr.h,为联网设备提供云端 ASR 通道,与本地引擎互补。

设计上,算法层与服务器层之间没有强绑定:只要满足 asr_server.h 的请求/事件协议,任何供应商引擎都可以接入,这正是该分层结构存在的根本原因。

主要实现剖析

服务框架层:asr_server.h 协议与任务注册

include_lib/server/asr_server.h 是整个 ASR 引擎对外的最小协议契约,全文仅三个枚举、一个结构体和一个联合体,但定义了引擎的全部对外交互面:

enum {
    STATE_OFF,
    STATE_ON,
};

enum {
    ASR_REQ_WAKE_ON_VOICE_ON,
    ASR_REQ_WAKE_ON_VOICE_OFF,
};

enum {
    ASR_SER_EVENT_WAKE,
};

struct asr_wake {
    void *enc_buf;
    int enc_buf_len;
    const char *data_file_path;
    u32 idle_gap_16ms;
    u32 run_gap_16ms;
    int best_sc;
};

union asr_req {
    struct asr_wake wake;
};

Source: asr_server.h

各部分的语义与设计意图:

  • STATE_OFF / STATE_ON:引擎(或唤醒功能)的运行状态。服务任务用这两个状态维护内部状态机,供请求处理时校验当前是否处于可接受状态。
  • ASR_REQ_WAKE_ON_VOICE_ON / OFF:外部(如按键、App 指令)向 ASR 服务发送"开启/关闭语音唤醒"请求。把唤醒开关做成请求而非直接调用,是为了让唤醒与识别都在同一任务上下文内串行执行,避免并发访问模型与音频缓冲。
  • ASR_SER_EVENT_WAKE:唤醒命中后由服务任务发出的事件,业务层监听该事件后进入识别会话(或点亮屏幕、开始录音等)。事件驱动是典型嵌入式状态机风格:引擎不主动回调,而是把状态变化"上报"给消息循环。
  • struct asr_wake:一次唤醒配置的载体——enc_buf/enc_buf_len 为编码后的唤醒模型缓冲区(预加载进内存,避免运行时读 Flash 抖动),data_file_path 指向模型文件路径,idle_gap_16ms 与 run_gap_16ms 分别是以 16ms 为单位的静默间隔与运行间隔(用于控制唤醒检测节奏、省电),best_sc 为最佳得分阈值参考。
  • union asr_req:为将来扩展其他请求类型预留的联合体(目前只有 wake 成员)。联合体保证请求消息体积最小,节省任务消息队列(qsize=64)的拷贝开销。

该任务在应用侧注册的实例如下(wifi_camera 与 wifi_ipc 配置一致):

{"asr_server",			15,	  1024,	  64   },

Source: apps/wifi_camera/app_main.c

即优先级 15、栈 1024 字节、消息队列 64。注意同表里 "wake-on-voice" 任务优先级为 7、栈 1024:唤醒任务优先级更低,说明唤醒检测被刻意设计为后台低开销活动,而 asr_server 优先级更高,保证识别阶段(计算密集)能及时抢占资源。

本地算法层:Fig ASR API(Roobo)

apps/common/asr/roobo/fig_asr_api.h 是本地识别引擎(Fig,来自 Roobo 方案)的公开 C 接口,采用"不透明句柄 + 生命周期管理"模式:

typedef void *FIG_INST;

int FigCreateInst(FIG_INST *inst, const char *szNnet, const char *szGraph);
int FigDestroyInst(FIG_INST inst);
int FigSetParameter(FIG_INST inst, AsrParamType eType, const char *szValue);
int FigStartProcess(FIG_INST inst);
int FigStopProcess(FIG_INST inst);
int FigWriteAudio(FIG_INST inst, char *pData, int nLen, int bFinish, PAsrResult *ppResult);

Source: fig_asr_api.h

关键设计:

  • FIG_INST 不透明句柄:引擎内部状态(神经网络、WFST 解码图、中间缓冲)全部隐藏在句柄之后,接口层零暴露,供应商可自由升级算法而保持 ABI 稳定。
  • 创建/销毁配对:FigCreateInst 需要两个资源参数——szNnet(神经网络模型,通常是训练好的声学模型文件路径)与 szGraph(WFST 加权有限状态转换器解码图,即命令词表编译产物);FigDestroyInst 负责释放。这对应 fig_asr_type.h 中的资源类型:
typedef enum {
    NNET_MODEL = 0,
    WFST_COMMAND,
    WFST_FILLER,
} AsrResType;

typedef enum {
    REC_CM_THRES,
    REC_RESET_CM_THRES,
    REC_DECODER_BEAM,
    REC_FILLER_NUM,
} AsrParamType;

typedef struct tagResult {
    int nBegin;
    int nEnd;
    char szText[32];
    short nWordId;
    int nCmScore;
} AsrResult, *PAsrResult;

Source: fig_asr_type.h

  • AsrResType 描述引擎持有的三类资源:声学模型(NNET_MODEL)、命令词 WFST 图(WFST_COMMAND)、填充词 WFST 图(WFST_FILLER)。命令词与填充词分开,是经典"关键词检出 + 拒识"设计:非命令词(填充词)命中时不输出结果,可显著降低误识别。
  • AsrParamType 是运行期可调参数:REC_CM_THRES 置信度(confidence measure)阈值,控制输出结果的严格程度;REC_RESET_CM_THRES 用于动态重置阈值;REC_DECODER_BEAM 解码束宽,权衡识别率与算力;REC_FILLER_NUM 填充词数量。FigSetParameter 统一以字符串传值,天然支持从配置文件读取。
  • AsrResult 输出结构:nBegin/nEnd 是命中词在音频流中的起止位置,szText[32] 是识别文本(固定 32 字节,命令词场景足够),nWordId 是词表 ID(便于程序化处理,不依赖字符串比较),nCmScore 是置信度得分。
  • FigWriteAudio 的 bFinish 标志:流式接口。bFinish=1 表示本次为音频流末尾,引擎需冲刷解码器并输出最终结果——这一"半开式"(half-open)语义让调用方既能边录边识别,又能在端点检测(VAD)结束时拿到确定结果。

简洁封装层:asr.h

apps/common/asr/roobo/asr.h 面向最简单的使用方式:初始化 → 循环喂音频 → 取结果。它把 Fig API 的复杂度收敛为四个函数,并明确约定了音频格式与帧长:

// Return value   : 0 - OK, -1 - Error
int  asr_init();

void asr_reset();

/*****************************************
* Input:
*      - buf      : Audio data (16k, 16bit, mono)
*      - buf_len  : Now must be 480 (30ms)
*
* Output:
*      - text     : The text of ASR
*      - score    : The confidence of ASR (Now not used)
*
* Return value    :  0 - No result
*                    1 - Has result
*                   -1 - Error
******************************************/
int  asr_process(short *buf, int buf_len, const char **text, float *score);

void asr_release();

Source: asr.h

设计要点:

  • 固定帧长契约:注释明确 buf_len 现在必须为 480(即 30ms @16kHz/16bit/mono)。这既是约束也是优化依据——内部环形缓冲与解码步进可按 480 对齐,避免动态分帧的运行时开销。
  • 返回值三态语义:0 表示当前帧无结果(正常、持续喂帧),1 表示本帧产出了识别文本,-1 表示错误(如未初始化、参数非法)。调用方只需轮询即可,无需理解引擎内部状态。
  • score 暂未使用:注释坦诚"Now not used",说明该接口保留了置信度输出通道,为将来按分数过滤预留。
  • asr_reset 与 asr_release 分离:reset 清空会话状态(结束上一轮识别、可立即开始新一轮),release 释放全部资源(退出识别功能时调用)。会话复用(reset)与资源销毁(release)的区分,对长时间运行设备至关重要——每轮唤醒对话只 reset、不 release,避免反复加载模型。

第三方供应商:Wanson 与腾讯云

  • Wanson(本地):apps/common/asr/wanson/fn_asr.h 为 Wanson 引擎头文件,实现以预编译库 cpu/wl82/liba/lib_wanson_asr.a 形式提供,与 Fig 引擎形成"双本地引擎"格局。应用层通过 CONFIG_ASR_ALGORITHM 宏条件编译选择算法(如 apps/wifi_story_machine/app_music_dui.c 中 #ifdef CONFIG_ASR_ALGORITHM 引用 aisp_open)。具体函数签名未在本页读取范围内,未在源码中进一步核实的细节不做展开。
  • 腾讯云(云端):lib/net/tencent/qcloud_iot_c_sdk/include/exports/qcloud_iot_export_asr.h 是腾讯云 IoT C SDK 导出的 ASR 接口,用于联网设备把音频上传云端识别。它属于完整的网络 SDK 子系统,接口细节不在本页范围内。

核心流程

ASR 引擎的典型运行过程是"唤醒 → 建实例 → 流式识别 → 取结果 → 收尾",其完整时序如下:

sequenceDiagram
    participant App as 业务应用/服务任务
    participant Svr as asr_server 任务
    participant Fig as Fig 引擎 (FIG_INST)
    participant Audio as 音频采集 (16k/16bit/mono)

    App->>Svr: ASR_REQ_WAKE_ON_VOICE_ON (asr_wake 参数)
    Svr->>Svr: 校验状态 STATE_OFF -> STATE_ON
    Note over Svr,Fig: 唤醒命中后
    Svr-->>App: ASR_SER_EVENT_WAKE
    App->>Svr: 开始识别会话
    Svr->>Fig: FigCreateInst(szNnet, szGraph)
    Fig-->>Svr: FIG_INST 句柄
    Svr->>Fig: FigSetParameter(REC_CM_THRES, ...)
    Svr->>Fig: FigStartProcess()

    loop 每 30ms 一帧 (480 samples)
        Audio->>Svr: buf[480]
        Svr->>Fig: FigWriteAudio(pData, 960B, bFinish=0, &pResult)
        alt 命中命令词
            Fig-->>Svr: AsrResult { szText, nWordId, nCmScore }
            Svr-->>App: 识别文本/词ID
        else 无结果
            Fig-->>Svr: pResult 为空
        end
    end

    App->>Svr: 会话结束 (VAD 超时/用户停止)
    Svr->>Fig: FigWriteAudio(..., bFinish=1, &pResult)
    Svr->>Fig: FigStopProcess()
    Svr->>Fig: FigDestroyInst(inst)
    Svr->>Svr: 状态复位,等待下一轮唤醒

流程关键点说明:

  1. 唤醒先行:识别会话不是任意时刻都能开始。asr_server 收到 ASR_REQ_WAKE_ON_VOICE_ON 后进入 STATE_ON,底层 wake-on-voice 任务(优先级 7,低于 asr_server 的 15)持续监听;命中后服务任务发出 ASR_SER_EVENT_WAKE,业务层才启动识别。这种两级流水线把功耗最高的识别阶段压缩到最短时间窗内。
  2. 实例生命周期:每轮识别 FigCreateInst → FigStartProcess → FigStopProcess → FigDestroyInst 成对出现,保证模型与解码图在会话结束后立即释放,为下一轮(或低功耗模式)腾出内存。
  3. 流式写音频:识别阶段以 30ms 帧为粒度 FigWriteAudio,返回值可即时反馈——既支持"边说话边出字"的流式体验,也支持等 bFinish=1 时一次性拿最终结果。
  4. 参数可调:在 Start 之前通过 FigSetParameter 设置置信度阈值与解码束宽,允许不同产品(安静家居 vs 嘈杂商场)运行时差异化调优,无需重新编译模型。

使用示例

以下示例均直接取自仓库源码,展示三种层级的典型用法。

示例一:服务层请求/事件协议(asr_server.h)

enum {
    STATE_OFF,
    STATE_ON,
};

enum {
    ASR_REQ_WAKE_ON_VOICE_ON,
    ASR_REQ_WAKE_ON_VOICE_OFF,
};

enum {
    ASR_SER_EVENT_WAKE,
};

struct asr_wake {
    void *enc_buf;
    int enc_buf_len;
    const char *data_file_path;
    u32 idle_gap_16ms;
    u32 run_gap_16ms;
    int best_sc;
};

Source: asr_server.h

业务侧据此构造唤醒请求:填充 struct asr_wake(预加载的编码唤醒模型 enc_buf、模型文件路径 data_file_path、16ms 粒度的静默/运行间隔、最佳得分参考 best_sc),以 ASR_REQ_WAKE_ON_VOICE_ON 发送给 asr_server;之后在消息循环中监听 ASR_SER_EVENT_WAKE 即可获知唤醒命中。

示例二:本地引擎生命周期(fig_asr_api.h)

typedef void *FIG_INST;

int FigCreateInst(FIG_INST *inst, const char *szNnet, const char *szGraph);
int FigDestroyInst(FIG_INST inst);
int FigSetParameter(FIG_INST inst, AsrParamType eType, const char *szValue);
int FigStartProcess(FIG_INST inst);
int FigStopProcess(FIG_INST inst);
int FigWriteAudio(FIG_INST inst, char *pData, int nLen, int bFinish, PAsrResult *ppResult);

Source: fig_asr_api.h

典型调用序列:FigCreateInst(&inst, nnet_path, graph_path) 创建实例 → FigSetParameter(inst, REC_CM_THRES, "60") 调阈值 → FigStartProcess(inst) 启动 → 循环 FigWriteAudio(inst, pcm, len, 0, &res) 喂音频并收集结果 → 结束时以 bFinish=1 冲刷 → FigStopProcess + FigDestroyInst 收尾。

示例三:简洁封装逐帧处理(asr.h)

// Return value   : 0 - OK, -1 - Error
int  asr_init();

void asr_reset();

/*****************************************
* Input:
*      - buf      : Audio data (16k, 16bit, mono)
*      - buf_len  : Now must be 480 (30ms)
*
* Output:
*      - text     : The text of ASR
*      - score    : The confidence of ASR (Now not used)
*
* Return value    :  0 - No result
*                    1 - Has result
*                   -1 - Error
******************************************/
int  asr_process(short *buf, int buf_len, const char **text, float *score);

void asr_release();

Source: asr.h

主循环写法:asr_init() 后,每次取 480 个采样(30ms)调用 asr_process;返回 1 时从 *text 读取识别文本;一轮会话结束后调用 asr_reset() 复用引擎;退出识别时调用 asr_release()。该接口屏蔽了 Fig 的实例管理与参数细节,适合业务快速集成。

示例四:引擎选择宏(wifi_story_machine)

#ifdef CONFIG_ASR_ALGORITHM
extern int aisp_open(u16 sample_rate);

Source: apps/wifi_story_machine/app_music_dui.c

应用层通过 CONFIG_ASR_ALGORITHM 编译宏选择具体算法实现(此处引用的 aisp_open 属于另一供应商接口),印证了"算法可替换"的分层设计:业务代码只依赖宏开关,不直接依赖某个引擎头文件。

配置选项

ASR 引擎的可配置项分布在三个层面:服务器任务注册参数、Fig 引擎运行参数、唤醒参数。

服务器任务注册参数

选项类型默认值说明
任务名string"asr_server"在 server 任务表中注册的名称,须与框架约定一致
优先级int15高于 "wake-on-voice"(7),保证识别阶段抢占资源
栈大小int1024任务栈字节数,识别调用链深度受此约束
消息队列深度int64请求消息容量,union asr_req 保持请求体最小以降低拷贝压力

(来源:apps/wifi_camera/app_main.c,wifi_ipc 配置相同)

Fig 引擎运行参数(AsrParamType)

枚举值说明典型用途
REC_CM_THRES置信度阈值控制输出严格度;调高降误识别、调低提召回
REC_RESET_CM_THRES重置置信度阈值会话间动态恢复默认阈值
REC_DECODER_BEAM解码束宽权衡识别率与 CPU 开销,束宽越大越慢但越准
REC_FILLER_NUM填充词数量配置拒识词数量,抑制非命令词误触发

FigSetParameter 统一以 const char *szValue 传值,便于从配置文件或服务器下发参数直接透传。

唤醒配置(struct asr_wake)

字段类型说明
enc_bufvoid *预加载的编码唤醒模型内存缓冲
enc_buf_lenint编码模型缓冲长度
data_file_pathconst char *唤醒模型文件路径
idle_gap_16msu32静默间隔(单位 16ms),控制检测节奏
run_gap_16msu32运行间隔(单位 16ms),省电相关
best_scint最佳得分参考,用于唤醒判定

简洁封装层约定

项值说明
音频格式16kHz / 16bit / monoasr_process 输入硬性要求
帧长480 samples(30ms)当前版本 buf_len 必须为 480
asr_process 返回值0 / 1 / -1无结果 / 有结果 / 错误

API Reference

Fig 引擎(fig_asr_api.h)

int FigCreateInst(FIG_INST *inst, const char *szNnet, const char *szGraph)

创建 ASR 引擎实例。

参数:

  • inst (FIG_INST *):输出参数,接收不透明实例句柄
  • szNnet (const char *):神经网络(声学)模型路径
  • szGraph (const char *):WFST 解码图(命令词表)路径

返回: int,0 成功,非零失败(具体错误码未在头文件定义)。

说明: 创建过程加载声学模型与解码图,应在识别会话开始前调用,与 FigDestroyInst 配对。

int FigDestroyInst(FIG_INST inst)

销毁引擎实例,释放模型与解码资源。

参数: inst (FIG_INST):待销毁的实例句柄。

返回: int,0 成功。

int FigSetParameter(FIG_INST inst, AsrParamType eType, const char *szValue)

设置运行参数(见上文 AsrParamType 表)。

参数:

  • inst (FIG_INST):实例句柄
  • eType (AsrParamType):参数类型
  • szValue (const char *):字符串形式的参数值

返回: int,0 成功。

int FigStartProcess(FIG_INST inst)

启动识别处理(进入可写音频状态)。

参数: inst (FIG_INST)。

返回: int,0 成功。

int FigStopProcess(FIG_INST inst)

停止识别处理。

参数: inst (FIG_INST)。

返回: int,0 成功。

int FigWriteAudio(FIG_INST inst, char *pData, int nLen, int bFinish, PAsrResult *ppResult)

写入一帧音频并(可能)返回识别结果。

参数:

  • inst (FIG_INST):实例句柄
  • pData (char *):PCM 音频数据(16kHz/16bit/mono)
  • nLen (int):数据字节数
  • bFinish (int):1 表示音频流结束,引擎冲刷解码器
  • ppResult (PAsrResult *):输出参数,命中时指向 AsrResult(含 szText/nWordId/nCmScore/nBegin/nEnd),无结果时为空

返回: int,0 成功。

简洁封装(asr.h)

int asr_init()

初始化 ASR 引擎(加载模型等一次性资源)。返回 0 成功,-1 错误。

void asr_reset()

重置会话状态,清空上一轮识别上下文,可立即开始新一轮识别(不释放资源)。

int asr_process(short *buf, int buf_len, const char **text, float *score)

逐帧识别。

参数:

  • buf (short *):音频数据,16kHz/16bit/mono
  • buf_len (int):采样点数,必须为 480(30ms)
  • text (const char **):输出识别文本
  • score (float *):置信度输出(当前版本未使用)

返回: 0 无结果;1 有结果(读取 *text);-1 错误。

Throws/错误: 头文件未声明异常,错误统一以 -1 返回值表示(如未初始化、帧长非法)。

void asr_release()

释放引擎全部资源,退出识别功能时调用。

故障模式、边界情况与并发

错误处理

  • asr_process 返回 -1:表示引擎错误(如未 asr_init、buf_len 非 480)。调用方必须检查返回值,不能把 -1 当"无结果"继续喂帧,否则可能掩盖引擎异常状态。
  • FigCreateInst / FigDestroyInst 失败:模型文件缺失或内存不足时返回非零。由于句柄是不透明指针,失败后 inst 内容不可用,调用方应终止会话并重试或回退到提示音(SDK 提供 AiAsrFail.mp3 提示资源,见 wifi_story_machine 的提示音表)。
  • 识别为空:静音或全是填充词时无输出,SDK 提供 AsrEmpty.mp3 提示资源(APP_LOCAL_PROMPT_ASR_EMPTY),业务层据此播报"没听清"。

边界条件

  • 帧长契约:asr_process 的 buf_len 被硬性约定为 480(30ms)。音频采集侧必须按此粒度切帧;若采集粒度不匹配,需在中间层重采样/缓冲对齐,否则引擎行为未定义。
  • szText[32] 定长缓冲:AsrResult.szText 固定 32 字节,命令词场景足够;若词表出现超长命令词,文本会被截断,业务侧应以 nWordId 为准做程序化匹配。
  • 唤醒参数以 16ms 为粒度:idle_gap_16ms/run_gap_16ms 均以 16ms 为单位,配置时需按此粒度换算。

并发与一致性

  • 单任务串行模型:asr_server 以独立任务运行,唤醒开关请求(ASR_REQ_WAKE_ON_VOICE_*)与识别会话都在该任务消息循环内处理,天然避免了对模型、音频缓冲的并发访问。业务层不得跨任务直接调用 Fig 接口,必须通过 server 消息间接驱动。
  • 唤醒与识别优先级分层:wake-on-voice(优先级 7)与 asr_server(优先级 15)形成"低开销监听 + 高优先级识别"的配合。唤醒命中的瞬间存在任务切换延迟,但识别帧率由 30ms 帧长兜底,通常可容忍。
  • 会话资源独占:FigCreateInst 创建的实例在本轮会话内独占模型资源,FigStopProcess/FigDestroyInst 前不得开启新一轮会话,否则可能造成资源泄漏或解码状态错乱。

性能与运维

  • 实时性预算:识别以 30ms 音频帧为输入,算法处理必须在帧间隔内完成(含 FigWriteAudio 内部解码)。解码束宽(REC_DECODER_BEAM)是主要性能旋钮:束宽越大识别率越高、CPU 占用越大,产品需按主控频率实测标定。
  • 内存占用:asr_server 栈仅 1024 字节,Fig 引擎的大块内存(声学模型、WFST 图、内部缓冲)应通过堆分配管理,避免压栈;唤醒模型建议预加载到 enc_buf(内存常驻),换取运行时无 Flash 读取抖动。
  • 任务优先级语义:asr_server 优先级 15 高于多数业务任务,识别会话期间会抢占 CPU;若同时有网络/显示关键路径,需评估整体调度余量(优先级数值越小越高的平台需按 SDK 约定核对)。
  • 编译期引擎选择:通过 CONFIG_ASR_ALGORITHM 等宏在编译期选定算法(Fig / Wanson / 云端),可裁剪未用引擎代码以减小固件体积;预编译库(如 lib_wanson_asr.a)按目标平台(cpu/wl82/)配套提供。

扩展点

  1. 接入新 ASR 供应商:只需满足 asr_server.h 的请求/事件协议(ASR_REQ_WAKE_ON_VOICE_*、ASR_SER_EVENT_WAKE、struct asr_wake),并把引擎调用封装进 asr_server 任务内部即可;union asr_req 预留了扩展新请求类型的空间。
  2. 运行参数动态下发:FigSetParameter 的字符串传值设计支持把阈值、束宽等参数接入配置系统或服务器下发通道,实现产品级远程调优而不改固件。
  3. 提示音资产替换:识别失败(AiAsrFail.mp3)、进入 ASR 模式(AiAsrMode.mp3)、识别为空(AsrEmpty.mp3)等提示音位于提示音映射表中,可替换音频文件以适配不同产品语种与话术。
  4. 上层封装复用:asr.h 的极简接口适合被业务模块直接复用;如需流式中间结果,可下沉到 Fig 层自行管理 AsrResult 的 nBegin/nEnd 时间戳。

测试

仓库中未发现针对 ASR 引擎的独立单元测试文件(apps/common/asr/ 目录仅包含引擎头文件与实现)。引擎验证主要依赖:

  • 应用级集成验证:wifi_story_machine 等应用通过提示音资产(AiAsrFail.mp3、AsrEmpty.mp3 等)反馈识别成败,可据此做端到端冒烟测试;
  • 模型/词表迭代:WFST_COMMAND/WFST_FILLER 图的替换与 REC_CM_THRES 阈值标定属于离线评测范畴,需在真实环境(信噪比、麦克风距离)下采集数据验证。

说明:本页基于仓库中可读取的头文件与任务注册代码整理;引擎内部实现以预编译库形式提供,函数内部算法细节未在源码中体现。

Related Links

  • asr_server.h — 服务层协议
  • fig_asr_api.h — Fig 引擎 API
  • fig_asr_type.h — 资源/参数/结果类型
  • asr.h — 简洁封装接口
  • fn_asr.h — Wanson 引擎接口
  • qcloud_iot_export_asr.h — 腾讯云 ASR
  • apps/wifi_camera/app_main.c — asr_server 任务注册
  • apps/wifi_story_machine/app_music_dui.c — 算法宏选择与提示音

相关目录页:语音唤醒(wake-on-voice / KWS)机制、server 框架任务模型、音频采集与处理链路、腾讯云 IoT 接入。

Next
LLM 与 AI 语音助手接入