# 功能说明

AIUI的离线识别是为了提高常见命令词的识别速度,提升体验效果加入的。

AIUI在没有离线识别的情况下,对例如上一首,下一首,暂停播放这些音乐控制命令,都会将音频上传到AIUI云端,云端在处理后将听写和语义的结果再下发到客户端。

AIUI开启离线命令词识别功能后,会在音频送到AIUI云端的同时送到本地的离线识别引擎进行识别。

# 感性认识

离线功能的核心是编写的离线命令词语法。先举个例子,感性的认识一下

#BNF+IAT 1.0 UTF-8;
!grammar main;
!slot <sleep>;
!start <sleep>;

<sleep>:你去睡觉吧!id(2001)|你去休息吧!id(2001)|睡觉去吧!id(2001)

当如上的离线语法构建启用后,你在说‘你去睡觉吧’,‘你去休息吧,‘睡觉去吧’中任何一句后,离线引擎都会识别成功返回对应项的信息结果给你(返回结果在下文中有示例)。

离线命令词并不会返回听写或者语义的结果,它是把音频与编写的离线语法中的规则做匹配,返回离线语法中对应匹配项的信息。

# 开启方法

① 云端模式:

"speech":{
        "intent_engine_type":"cloud"
}

AIUI的默认模式,不开启离线功能,全部使用云端语义和听写功能。

② 本地模式:

"speech":{
        "intent_engine_type":"local"
}

AIUI完全离线,只使用本地的离线命令词功能。 在此模式下AIUI功能非常受限,只能完成简单命令词的识别。

③ 混合模式:

"speech":{
        "intent_engine_type":"mixed"
}

混合模式下,音频会同时送到本地离线引擎和云端解析。 结果选择策略是哪个先返回有效结果,就采用哪个。

另外需要注意aiui.cfg中要包含如下配置项

// 离线语法识别参数
"asr":{
    "threshold":"50",
    "res_type":"assets",
    "res_path":"asr/common.jet"
}

# 使用步骤

# 离线命令语法编写

离线命令语法是使用巴科斯范式(BNF)描述语音识别的语法。语法文件包括HEADER和BODY。

!grammar main;
!slot <sleep>;
!start <sleep>;

<sleep>:你去睡觉吧!id(2001)|你去休息吧!id(2001)|睡觉去吧!id(2001)

语法编写的具体文档可以参考讯飞云平台上识别语法分享–在线语法和离线语法编写指南 (opens new window)。 章节附录也有AIUIProdutDemo使用离线语法示例。

# 构建离线语法

在AIUI中定义了CMD_BUILD_GRAMMAR命令构建语法。

SDK使用:

AIUIMessage buildGrammar = new AIUIMessage(AIUIConstant.CMD_BUILD_GRAMMAR,
        0, 0, grammar_str, null); //grammar_str为编写的离线语法
mAIUIAgent.sendMessage(buildGrammar);

串口:

//构造如下json,放入主控消息类型中发送给AIUI。

{
    "type": "aiui_msg",
    "content": {
        "msg_type": 16, //CMD_BUILD_GRAMMAR  重置AIUI唤醒状态
        "arg1": 0,
        "arg2": 0,
        "params": "grammar_str" //grammar_str为编写的离线语法
    }
}

每次调用命令构建的语法都会覆盖先前对应的GrammerID的离线语法。

该命令是有返回的,所以通过EVENT_CMD_RETURN事件的arg2参数可以判断构建结果。

构建使用离线语法中的错误码参考AIUI错误码

# 离线语法槽更新

在离线语法中有槽的定义(具体定义可以参考上面提到的语法文档),主要作用就是在语法构建生效后,可以动态更新当前生效的语法中的部分内容。

定义了一个打电话的离线语法

!slot contact
!start <call>

<call>:打电话给<contact>
<contact>:张三|李四

已经通过AIUI构建了语法,并且使用了。假如当前通讯录有新联系人添加,那我们也要更新离线语法中(slot)槽contact的内容:

{
    "name": "contact",     //槽名称
    "content":"张三\n李四\n王二\n" //词表内容
}

使用命令CMD_UPDATE_LOCAL_LEXICON(17),将params设置为上面的json,发送给AIUI即可。

SDK或者串口的具体使用方式可以参考上面构建语法时的操作。

# 结果解析

通过解析结果params下的sub字段,判断结果属于哪种类型,离线命令词识别结果sub字段为asr

离线命令识别结果(asr)举例如下:

"result": {
    "sid": "",
    "intent": {
        "ws": [{
            "slot": "<sleep>",
            "cw": [{
                "w": "你去睡觉吧",
                "id": 2001,
                "sc": 54
            }]
        }],
        "rc": 0
    }
},
"info": {
    "data": [{
        "params": {
            "sub": "asr"
        }
    }]
}

主要解析intent中ws下的字段,根据先前编写的离线语法文件,很容易理解代表的字段。

id的字段跟语法中声明的对应,id的声明方法参考上面提到的语法文档。

# 注意事项

# 离线命令识别与线上语义结合

AIUI在纯离线模式下,功能很受限。如果需要使用离线命令的话,推荐使用混合模式,提高常见命令短语的识别速度,提升体验。

离线命令词的功能会比线上识别要弱一点,所以可能存在说法在离线命令词没有识别结果,在云端听写会正确听写结果。 如果在云端没有配置对应的语义,本次结果就会拒识。所以混合模式下,在本地定义离线命令语法的同时在云端说法也有对应的语义,这样会减少拒识的情况,提升体验。

# 附录

# AIUIProductDemo默认使用的离线语法文件

#BNF+IAT 1.0 UTF-8;
!grammar main;

!slot <music>;
!slot <sleep>;
!slot <smarthome>;
!slot <devices>;

!start <operation>;
<operation>:<music>|<sleep>|<smarthome>;

<music>:上一首!id(1001)
                |下一首!id(1002)|换一首!id(1002)
                |暂停播放!id(1003)|暂停!id(1003)
                |继续!id(1004)|继续播放!id(1004)
                |大点声!id(1005)|大点儿声!id(1005)|增大音量!id(1005)|再大点声!id(1005)|听不清!id(1005)
                |小点声!id(1006)|小点儿声!id(1006)|降低音量!id(1006)|再小点声!id(1006)|太吵了!id(1006);

<sleep>:你去睡觉吧!id(2001)|你去休息吧!id(2001)|睡觉去吧!id(2001)
                |休息去吧!id(2001)|不是跟你说话!id(2001)|不是在跟你说话!id(2001)
                |没跟你说话!id(2001)|没和你说话!id(2001)|跪安吧!id(2001);

<smarthome>:打开台灯!id(3001)
                    |打开电灯!id(3001)|把灯打开!id(3001)|把电灯打开!id(3001)|把台灯打开!id(3001)|开灯!id(3001)
                    |关灯把电灯关了!id(3002)|关闭台灯!id(3002)|关灯!id(3002)|把电灯关了!id(3002)|把电灯关闭!id(3002)|把灯关了!id(3002)

                    |打开空调!id(3003)|把空调打开!id(3003)|屋里有点冷!id(3003)|屋里有点儿冷!id(3003)|屋里有点热!id(3003)|屋里有点儿热!id(3003)
                    |关闭空调!id(3004)|空调关闭!id(3004)|把空调关闭!id(3004)|把空调关了!id(3004)

                    |打开加湿器!id(3005)|把加湿器打开!id(3005)|屋里有点干!id(3005)|屋里有点儿干!id(3005)
                    |关闭加湿器!id(3006)|把加湿器关闭!id(3006)

                    |打开电风扇!id(3007)|把电风扇打开!id(3007)
                    |关闭电风扇!id(3008)|把电风扇关闭!id(3008)|把电风扇关了!id(3008);