# 语音唤醒
[TOC]
语音唤醒(**VoiceWakeuper**)通过辨别输入的音频中特定的词语(如“讯飞语点”),返回被命中(唤醒)结果,应用通过回调的结果,进行下一步的处理,如点亮屏幕,或与用户进行语音交互等。唤醒资源中含有一个或多个资源,只要命中其中一个,即可唤醒。需下载使用对应的语音唤醒SDK。
唤醒的参数主要有:
* 唤醒资源路径(IVW_RES_PATH)
* 唤醒类型(IVW_SST)
* 唤醒门限(IVW_THRESHOLD)
* 是否持续唤醒(KEEP_ALIVE)
~~~
// 唤醒资源路径,需下载使用对应的语音唤醒SDK。
mIvw.setParameter( SpeechConstant.IVW_RES_PATH, ivwResPath );
// 唤醒类型
mIvw.setParameter( SpeechConstant.IVW_SST, ivwSst );
// 唤醒门限
mIvw.setParameter( SpeechConstant.IVW_THRESHOLD, threshold );
// 持续唤醒
mIvw.setParameter( SpeechConstant.KEEP_ALIVE, keepAlive );
ret = mIvw.startListening( listener );
~~~
唤醒状态(结果和错误)通过 listener 的回调获取。
## 唤醒识别
唤醒类型中,有一种类型叫“唤醒识别”(oneshot),是在说唤醒词后,马上说识别命令,SDK 则在唤醒的同时,对命令进行识别,如“讯飞语点,打电话给张三”,其中,“讯飞语点”是唤醒词,“打电话给张三”是命令(语法识别中的某条规则,关于语法识别可以参考对应的章节)。从以上特点可以知道,在唤醒识别时,还需要传入在线语法ID,或本地语法路径。
~~~
// 设置业务类型为唤醒识别
mIvw.setParameter( SpeechConstant.IVW_SST,"oneshot" );
//设置识别引擎,只影响唤醒后的识别(唤醒本身只有离线类型)
mIvw.setParameter( SpeechConstant.ENGINE_TYPE, asrEngineType );
if( SpeechConstant.TYPE_CLOUD.equals(asrEngineType) ){
//设置在线识别的语法ID
mIvw.setParameter( SpeechConstant.CLOUD_GRAMMAR, grammarID );
}else{
// 设置本地识别资源
mIvw.setParameter( ResourceUtil.ASR_RES_PATH, asrResPath );
// 设置语法构建路径
mIvw.setParameter( ResourceUtil.GRM_BUILD_PATH, grmPath );
}
ret = mIvw.startListening( listener );
~~~
唤醒识别时,唤醒的状态获取不变,而识别的结果则通过回调中的事件获取。
## 闭环优化
闭环优化是针对开发者的唤醒资源由云端优化系统不断优化的功能。通过开发者 APP 使用场景,本地唤醒 SDK 自动挑选音频数据上传至云端,进行训练生成优化唤醒资源。开发者 APP 使用场景中,优化唤醒资源在相比原有资源在提升唤醒率及抑制误唤醒方面有良好的表现。持续优化包含两种网络模式:
* 模式 0:关闭优化功能,禁止向服务端发送本地挑选数据及启动唤醒时进行查询下载;
* 模式 1:开启优化功能,允许向服务端发送本地挑选数据。需要开发者自行进行优化资源的查询下载,及对资源的使用进行管理;
~~~
// 设置开启优化功能
mIvw.setParameter( SpeechConstant.IVW_NET_MODE, "1" );
~~~
可以每隔一段时间后查询是否有资源更新,如每周,每月,当有资源更新时,下载新的资源以替换当前使用的资源.
~~~
// 查询资源
mIvw.queryResource( ivwResPath, requestListener );
private RequestListener requestListener = new RequestListener() {
... // 其他回调函数
@Override
public void onBufferReceived(byte[] buffer) {
try {
String resultInfo = new String(buffer, "utf-8");
JSONTokener tokener = new JSONTokener(resultInfo);
JSONObject object = new JSONObject(tokener);
int ret = object.getInt("ret");
if(ret == 0) {
String uri = object.getString("dlurl");
String md5 = object.getString("md5");
//下载资源,下载状态通过 wakeListener 获取
mIvw.downloadResource( downloadUri, filePath, downloadMd5, wakeListener );
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
~~~
## AIMIC唤醒
针对智能硬件,MSC SDK提供了可处理多声道音频,获取音频中有效了几路音频,同时进行唤醒的模式,我们称之为AIMIC唤醒。在这种模式下,需要使用额外的音频处理库 libaimic.so,结合智能硬件的加密模块,对多声道的原始音频处理,并在唤醒结果中,包含当前唤醒的角度等信息。
目前AIMIC唤醒为定制方案,可通过文章最后的联系方式与我们商务同事联系获取SDK。
在AIMIC唤醒中,包含以下与普通唤醒不同的参数:
* 唤醒路数(IVW_CHANNEL_NUM)
* 音频源(AUIOD_SOURCE)
* ALSA录音卡号(IVW_ALSA_CARD)
* ALSA录音采样率(IVW_ALSA_RATE)
~~~
// 如果设置 AUDIO_SOURCE 为 -3,则要求项目中包含 alsa 的SDK
// 同时需要设置与麦克风硬件一致的 录音卡号和采样率 ,默认
// 卡号=2, 采样率=16000。更多说明,参考《MSC Reference Manual.html》相关参数。
//mIvw.setParameter( SpeechConstant.AUDIO_SOURCE, "-3" );
//mIvw.setParameter( SpeechConstant.IVW_ALSA_CARD, X ); //X为硬件实际可用的卡号
//mIvw.setParameter( SpeechConstant.IVW_ALSA_RATE, Y ); //Y为硬件实际可用的采样率
// 设置唤醒路数
mIvw.setParameter(SpeechConstant.IVW_CHANNEL_NUM, "3");
~~~
AIMIC唤醒成功后,除在 WakeuperListener 的onResult 函数返回结果后,还通过 onEvent 返回单声道 16K 可用于语音识别音频。
~~~
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
if( SpeechEvent.EVENT_RECORD_DATA==eventType ){
//获取用于识别的音频
byte[] data = obj.getByteArray(SpeechEvent.KEY_EVENT_RECORD_DATA);
}
}
~~~