voice-ai-sdk
若琪语音交互SDK - C++接口
若琪语音交互sdk

1. 概述

封装若琪语音交互协议。
通过此sdk可接入使用若琪智能音箱语音交互功能。

2. 功能

简单描述sdk工作的场景
向sdk输入语音数据,sdk回调语音数据识别结果,例如"你好"。
随后sdk回调"你好"应该执行的响应指令,一般为一段需要语音合成的文字: "你好呀,今天天气真美好"
将"你好呀,今天天气真美好"文字输入sdk进行语音合成,sdk回调这段文字合成的音频数据库,可由设备播放。
更详细的sdk使用方式请阅读类接口定义

3. 示例

3.1 创建实例

auto voiceAI = VoiceAI::newInstance();
voiceAI->config(VoiceAI::Option::SPEECH_URI, options.speechUri.c_str());
voiceAI->config(VoiceAI::Option::REPORT_URI, options.restUri.c_str());
voiceAI->config(VoiceAI::Option::AUTHINFO, options.key.c_str(),
options.secret.c_str(), options.deviceTypeId.c_str(),
options.deviceId.c_str());
voiceAI->config(VoiceAI::Option::AUDIO_CODEC, VoiceAI::AudioCodec::OPU);
voiceAI->config(VoiceAI::Option::CONTINUOUS_DIALOGUE, contDiag ? 1 : 0);
voiceAI->setVoiceCallback(callbackObject);
voiceAI->setActionCallback(callbackObject);

3.2 回调对象

class MyCallbackObject : public VoiceAI::VoiceCallback, public VoiceAI::ActionCallback {
// callbacks of VoiceAI::VoiceCallback
void onAccept(const string& status, void* userp) {
if (status != "accept" && status != "none") {
KLOGD(TAG, "仲裁或二次确认失败(%s),关闭拾音", status.c_str());
pickup(false);
}
}
void onAsr(const string& asr, bool intermediate, void* userp) {
// 语音识别完整结果已得到,结束录音
if (!intermediate)
pickup(false);
}
void onResult(const string& nlp, const string& action, void* userp) {
// 一般不需要处理nlp, action, sdk会内部执行
}
void onVoiceError(int32_t err, void* userp) {
KLOGD(TAG, "onVoiceError: %d, userdata %p", err, userp);
pickup(false);
// 语音识别错误可能需要设备播报错误提示
}
// callbacks of VoiceAI::VoiceCallback
// session的概念,请参考接口文档内的描述
// 简单程序可以不用处理session
void onSessionStart(shared_ptr<VoiceAI::Session>& sess) {
KLOGD(TAG, "onSessionStart: %s", sess->getAppId().c_str());
}
void onSessionEnd(shared_ptr<VoiceAI::Session>& sess) {
KLOGD(TAG, "onSessionEnd: %s", sess->getAppId().c_str());
}
void onSessionActionCompleted(shared_ptr<VoiceAI::Session>& sess, void* userp) {
KLOGD(TAG, "onSessionActionCompleted: %s, userdata %p",
sess->getAppId().c_str(), userp);
}
void onPlayTts(shared_ptr<VoiceAI::Session>& sess, const string& text) {
KLOGD(TAG, "onPlayTts[%s]: %s", sess->getAppId().c_str(), text.c_str());
}
void onStopTts(shared_ptr<VoiceAI::Session>& sess) {
KLOGD(TAG, "onStopTts[%s]", sess->getAppId().c_str());
}
void onPlayMedia(shared_ptr<VoiceAI::Session>& sess, const string& url,
uint32_t position) {
KLOGD(TAG, "onPlayMedia[%s]: %s, %u", sess->getAppId().c_str(),
url.c_str(), position);
}
int32_t onStopMedia(shared_ptr<VoiceAI::Session>& sess) {
KLOGD(TAG, "onStopMedia[%s]", sess->getAppId().c_str());
return 0;
}
void onPickup(shared_ptr<VoiceAI::Session>& sess, bool open,
uint32_t duration) {
KLOGD(TAG, "onPickup[%s]: %d, %u", sess->getAppId().c_str(), open, duration);
}
// 本地技能的状态及动作回调
// 属于比较复杂的运用,只涉及云技能的情况下,不用处理
void onNativeAction(shared_ptr<VoiceAI::Session>& sess, const string& nlp) {
}
void onNativePause(shared_ptr<VoiceAI::Session>& sess) {
}
void onNativeResume(shared_ptr<VoiceAI::Session>& sess) {
}
void onNativeExit(shared_ptr<VoiceAI::Session>& sess) {
}
void onActionError(int32_t err, void* userp) {
KLOGD(TAG, "onActionError: %d, userdata = %p", err, userp);
}
};

3.3 输入语音

开始一次语音交互
按键录音,传null就可以
前端激活词激活,需要传入VoiceOptions对象,由前端给出的信息填充,具体参数见接口文档
voiceAI->startVoice(nullptr);
分多次传入语音数据
data为音频数据内存指针,可以是pcm数据,也可以是opu格式的数据
详见接口文档
voiceAI->writeVoice(data, len);
云端识别语音结尾,一般不需要调用 voiceAI->endVoice()
endVoice()用于提前结束语音交互

3.4 语音合成

传入文本,获得音频数据流对象
auto ttsStream = voiceAI->textToSpeech(text);
读取音频数据流, 读取为阻塞过程,应在独立线程中进行
while (true) {
auto c = ttsStream->read(buffer, bufsize);
// c == 0,音频流结束
if (c == 0)
break;
// TODO: 处理读取的音频数据, c为本次读取的字节数
}
// 音频流结束后,可以通过getError()得知是正常结束还是出错
ttsStream->getError();