灵云SDK开发手册(C API)  5.2
 全部 结构体 函数 变量 类型定义 枚举 枚举值  
VPR能力

以下描述了如何使用灵云VPR能力。

1. VPR简介

VPR 声纹识别能力,对特定的声音进行模型注册和模型训练后,支持对未知音频的校验。

2. 选择模块和能力

灵云可以提供云端和本地端的声纹识别能力. 无论使用云端或本地端的声纹识别能力,基础模块 hci_vpr都是需要的。 使用云端能力时,需要加上hci_vpr_cloud_recog模块; 使用本地端能力时,需要加上hci_vpr_local_recog模块

3. 声纹特征注册和训练

当调用hci_vpr_enroll接口进行注册时,用户唯一标识可以由服务端产生,也可以由用户自己指定,但必须要保证该标识的唯一性。 注册成功后,可以对该声纹模型进行多次训练。

示例代码如下:

enrollData.uiVoiceDataCount = nEnrollDataCount;
enrollData.psVoiceDataList = enrollItemArray;
//userID为非必填项,但要注意,开发者需要确保userID的唯一性。
string enrollConfig += "audioformat=" + audioformat;
enrollConfig += ",encode=none";
VPR_ENROLL_RESULT enrollResult;
HCI_ERR_CODE errCode = hci_vpr_enroll(nSessionId,&enrollData,enrollConfig.c_str(),&enrollResult);
if (errCode != HCI_ERR_NONE)
{
printf("hci_vpr_enroll return %d\n",errCode);
return;
}

4. 声纹特征确认

声纹模型注册和训练成功后,可以对音频数据进行校验,以判断用户唯一标识和音频数据是否相符。

示例代码如下:

//userID 为必填项,判断声纹数据特征与此 userID对应的模型是否相同。
string verifyConfig = "userid=" + userID;
verifyConfig = "audioformat=" + audioformat;
verifyConfig += ",encode=none";
VPR_VERIFY_RESULT pVerifyResult;
errCode = hci_vpr_verify(nSessionId, voiceData.m_pBuf, voiceData.m_nLen, verifyConfig.c_str(), &pVerifyResult);
if( errCode != HCI_ERR_NONE )
{
printf( "hci_vpr_verify return %d\n", errCode );
hci_vpr_session_stop(nSessionId);
return;
}
printf( "hci_vpr_verify success\n" );
if (pVerifyResult.eStatus == VPR_VERIFY_STATUS_MATCH)
{
printf( "voice data matches with user id:%s !\n",userID.c_str());
}
else
{
printf("voice data doesn't match with user id:%s !\n",userID.c_str());
}
errCode = hci_vpr_free_verify_result(&pVerifyResult);
if( errCode != HCI_ERR_NONE )
{
printf( "hci_vpr_free_verify_result return %d\n", errCode );
hci_vpr_session_stop(nSessionId);
return;
}
printf( "hci_vpr_free_verify_result success\n" );

5. 声纹特征辨识

对音频数据校验后,需要对音频数据识别,识别结果以分数形式给出。

示例代码如下:

string identify_config = "encode=speex,audioformat= pcm16k16bit,";
identify_config += "groupid=" + groupId;
VPR_IDENTIFY_RESULT identifyResult;
err_code = hci_vpr_identify(session_id, voiceData.buff_, voiceData.buff_len_, identify_config.c_str(), &identifyResult);
if( err_code != HCI_ERR_NONE )
{
printf("hci_vpr_identify return (%d:%s) \n",err_code,hci_get_error_info(err_code));
hci_vpr_session_stop(session_id);
return;
}
PrintIdentifyResult(identifyResult);
hci_vpr_free_identify_result(&identifyResult);
err_code = hci_vpr_session_stop(session_id);
if( err_code != HCI_ERR_NONE )
{
printf( "hci_vpr_session_stop return %d\n", err_code );
return ;
}
printf( "hci_vpr_session_stop success\n" );

在云端实时识别模式下(本地暂不支持),调用 注册、确认和辨识接口,函数不会将传入的pvVoiceData当成所有的识别数据进行一次完整的识别,用户可以将音频数据分多次来调用 这几个函数。 SDK内部会同时进行状态识别,当检测到音频传输结束,会返回结束状态,用户传入空包即可停止检测。

辨识模块的实时识别的示例如下:

int nPerLen = 3200*20;
int nLen = 0; // 当前已传入的长度
char indextmp[10];
while (nLen + nPerLen < voiceData.buff_len_)
{
// 本次要传入的参与识别的数据长度,
// 剩余的多于nPerLen则传入nPerLen个字节,若不足则传入剩余数据
int nThisLen = 0;
if( voiceData.buff_len_ - nLen >= nPerLen )
{
nThisLen = nPerLen;
}
else
{
nThisLen = voiceData.buff_len_ - nLen;
}
//printf("index:%d ",index);
err_code = hci_vpr_identify(session_id, voiceData.buff_+nLen, nThisLen, identify_config.c_str(), &identifyResult);
if( err_code == HCI_ERR_VPR_REALTING_END )
{
// 检测到末端了,跳出循环
break;
}
nLen += nThisLen;
}
// 若未检测到端点,但数据已经传入完毕,则需要告诉引擎数据输入完毕
// 或者检测到末端了,也需要告诉引擎,获取结果
if( err_code == HCI_ERR_VPR_REALTIME_WAITING || err_code == HCI_ERR_VPR_REALTING_END )
{
err_code = hci_vpr_identify(session_id, NULL, 0, identify_config.c_str(), &identifyResult);
}
if( err_code == HCI_ERR_VPR_REALTING_END )
{
// 输出识别结果
PrintIdentifyResult(identifyResult);
// 释放识别结果
hci_vpr_free_identify_result(&identifyResult);
if( err_code != HCI_ERR_VPR_REALTING_END )
{
printf( "hci_vpr_free_recog_result return %d\n", err_code );
hci_vpr_session_stop(session_id);
return ;
}
printf( "hci_vpr_free_recog_result success\n" );
}
else
{
printf( "hci_vpr_recog failed with %d\n", err_code );
}