286 lines
9.9 KiB
C++
286 lines
9.9 KiB
C++
|
|
|||
|
#include <BDuerSDK.h>
|
|||
|
#include <iostream>
|
|||
|
#include <fcntl.h>
|
|||
|
#include <cstring>
|
|||
|
#include <unistd.h>
|
|||
|
#include <sys/select.h>
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
using namespace std;
|
|||
|
using namespace bduer;
|
|||
|
|
|||
|
char speech_resources_path[] = "/root/duer_demo/resources/";
|
|||
|
char sdk_configs_path[] = "/root/duer_demo/sdkconfigs/";
|
|||
|
char record_pcm[] = "/root/duer_demo/records/record.pcm";
|
|||
|
|
|||
|
BDuerSDK* duerSDK;
|
|||
|
void* push_audio_test(void* args);
|
|||
|
void push_audio_stream(char* stream, unsigned int streamSize);
|
|||
|
|
|||
|
class ReqBack : public IBDuerSDKCallback {
|
|||
|
public:
|
|||
|
ReqBack() {
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
~ReqBack() {
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void remote_callback(BDuerMessage& message) {
|
|||
|
}
|
|||
|
|
|||
|
void message_callback(BDuerMessage& message) {
|
|||
|
if (strcmp(BDUER_CALLBACK_REGISTER_SUCCESS, message.get_name()) == 0) {
|
|||
|
cout << "注册成功" << endl;
|
|||
|
int req;
|
|||
|
BDuerMessage message;
|
|||
|
message.set_name(BDUER_CMD_START);
|
|||
|
message.set_parameter(BDUER_PARAM_KEY_SPEECH_ENGINE_SUPPORT,
|
|||
|
SPEECH_SUPPORT_WAKEUP_AND_ASR);
|
|||
|
message.set_parameter(BDUER_PARAM_KEY_AFTER_WAKE_UP, AFTER_FINISH_WAITING);
|
|||
|
message.set_parameter(BDUER_PARAM_KEY_SPEECH_RES_FILE_PATH,
|
|||
|
speech_resources_path, strlen(speech_resources_path) + 1);
|
|||
|
message.set_parameter(BDUER_PARAM_KEY_SDK_CONFIG_FILE_PATH,
|
|||
|
sdk_configs_path, strlen(sdk_configs_path) + 1);
|
|||
|
duerSDK->post(message, &req);
|
|||
|
|
|||
|
pthread_t pid;
|
|||
|
pthread_create(&pid, NULL, push_audio_test, NULL);
|
|||
|
|
|||
|
} else if (strcmp(BDUER_CALLBACK_ASR, message.get_name()) == 0) {
|
|||
|
int status;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_ASR_STATUS, status);
|
|||
|
char* word;
|
|||
|
int len;
|
|||
|
|
|||
|
switch (status) {
|
|||
|
case ASRStatusStart: {
|
|||
|
cout << "识别开始:" << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case ASRStatusVadEnd: {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case ASRStatusFlushData: {
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_ASR_DATA, word, len);
|
|||
|
cout << "中间识别结果: " << word << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case ASRStatusFinish: {
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_ASR_DATA, word, len);
|
|||
|
cout << "识别结果: " << word << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case ASRStatusCancel: {
|
|||
|
cout << "识别取消" << endl;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case ASRStatusMeterLevel: {
|
|||
|
int volume;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_ASR_METER_LEVEL, volume);
|
|||
|
//cout << "音量为:%d" << volume << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
;
|
|||
|
}
|
|||
|
} else if (strcmp(BDUER_CALLBACK_TTS, message.get_name()) == 0) {
|
|||
|
int status;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_TTS_STATUS, status);
|
|||
|
|
|||
|
switch (status) {
|
|||
|
case TTSStatusBegin: {
|
|||
|
cout << "语音合成开始:" << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case TTSStatusAudioData: {
|
|||
|
/**
|
|||
|
* char *stream 是返回的tts数据
|
|||
|
* int length 是返回的tts的数据长度
|
|||
|
*/
|
|||
|
char* stream;
|
|||
|
int length;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_TTS_AUDIO_DATA, stream, length);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case TTSStatusFinish: {
|
|||
|
cout << "语音合成结束..." << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
;
|
|||
|
}
|
|||
|
} else if (strcmp(BDUER_CALLBACK_DUER, message.get_name()) == 0) {
|
|||
|
char* content;
|
|||
|
int len;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_DUER_SERVER_CONTENT, content, len);
|
|||
|
cout << "度秘后端解析返回结果: " << content << endl;
|
|||
|
} /*else if (strcmp(BDUER_CALLBACK_HTTP_RESPONSE, message.get_name()) == 0) {
|
|||
|
char* content;
|
|||
|
int length = 0;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_HTTP_RESPONSE, content, length);
|
|||
|
//@
|
|||
|
Json::Reader reader;
|
|||
|
Json::Value data_json;
|
|||
|
bool ret = reader.parse(content, data_json);
|
|||
|
if (ret) {
|
|||
|
const Json::Value &result = data_json["result"];
|
|||
|
if (result.isMember("directives")) {
|
|||
|
const Json::Value &directives = result["directives"];
|
|||
|
if (directives.isArray()) {
|
|||
|
for (int i = 0; i < directives.size(); ++i) {
|
|||
|
const Json::Value &one_directive = directives[i];
|
|||
|
if (one_directive.isMember("header")) {
|
|||
|
const Json::Value &header = one_directive["header"];
|
|||
|
string nameSpace = header["namespace"].asString();
|
|||
|
string name = header["name"].asString();
|
|||
|
if (nameSpace == "SpeechSynthesizer" && name == "Speak") {
|
|||
|
const Json::Value &payload = one_directive["payload"];
|
|||
|
const Json::Value &content = payload["content"];
|
|||
|
if (content.isArray()) {
|
|||
|
string voice = content[0].asString();
|
|||
|
std::cout << "network result voice :" << voice << endl;
|
|||
|
if (voice.length() > 0) {
|
|||
|
const char *ttsVoice = voice.c_str();
|
|||
|
int length = strlen(ttsVoice);
|
|||
|
BDuerMessage msg;
|
|||
|
msg.set_name((char *) BDUER_CMD_TTS_STR);
|
|||
|
msg.set_parameter((char *) BDUER_PARAM_KEY_TTS_STR,
|
|||
|
ttsVoice, length);
|
|||
|
int req = 0;
|
|||
|
duerSDK->post(msg, &req);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}*/ else if (strcmp(BDUER_CALLBACK_WAKEUP, message.get_name()) == 0) {
|
|||
|
int status;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_WAKEUP_STATUS, status);
|
|||
|
|
|||
|
switch (status) {
|
|||
|
case WakeupStatusTriggered: {
|
|||
|
int req;
|
|||
|
// printf("唤醒成功");
|
|||
|
cout << "唤醒成功" << endl;
|
|||
|
//进入识别模式
|
|||
|
BDuerMessage message;
|
|||
|
message.set_name((char*) BDUER_CMD_OPEN_SPEECH_ENGINE);
|
|||
|
message.set_parameter(BDUER_PARAM_KEY_OPEN_SPEECH_ENGINE, SPEECH_ENGINE_ASR);
|
|||
|
duerSDK->post(message, &req);
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
} else if (strcmp(BDUER_CALLBACK_FINAL, message.get_name()) == 0) {
|
|||
|
char* errorMsg;
|
|||
|
int len;
|
|||
|
int errorCode;
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_ERROR_CODE, errorCode);
|
|||
|
message.get_parameter(BDUER_PARAM_KEY_ERROR_DESC, errorMsg, len);
|
|||
|
|
|||
|
switch (errorCode) {
|
|||
|
case BDuerTTSErrorCode :
|
|||
|
cout << "ERROR CODE: BDuerTTSErrorCode, Error MSG: " << errorMsg << endl;
|
|||
|
break;
|
|||
|
|
|||
|
case BDuerSDKFinishCode:
|
|||
|
cout << " BDuerSDKFinishCode " << endl;
|
|||
|
break;
|
|||
|
|
|||
|
case BDuerRegisterErrorCode:
|
|||
|
cout << "ERROR CODE: BDuerRegisterErrorCode, Error MSG: " << errorMsg << endl;
|
|||
|
break;
|
|||
|
|
|||
|
case BDuerWakeupErrorCode:
|
|||
|
cout << "ERROR CODE: BDuerWakeupErrorCode, Error MSG: " << errorMsg << endl;
|
|||
|
break;
|
|||
|
|
|||
|
case BDuerASRErrorCode:
|
|||
|
cout << "ERROR CODE: BDuerASRErrorCode, Error MSG: " << errorMsg << endl;
|
|||
|
break;
|
|||
|
|
|||
|
case BDuerSDKErrorCode:
|
|||
|
cout << "ERROR CODE: BDuerSDKErrorCode, Error MSG: " << errorMsg << endl;
|
|||
|
break;
|
|||
|
|
|||
|
case BDuerDUMIServerErrorCode:
|
|||
|
cout << "ERROR CODE: BDuerDUMIServerErrorCode, Error MSG: " << errorMsg << endl;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
void* push_audio_test(void* args) {
|
|||
|
char audioBuf[3200] = {0};
|
|||
|
FILE* fp = fopen(record_pcm, "rb");
|
|||
|
|
|||
|
if (fp != NULL) {
|
|||
|
|
|||
|
while (!feof(fp)) {
|
|||
|
size_t readCount = fread(audioBuf, 1, 3200, fp);
|
|||
|
|
|||
|
//cout << "DataRead: " << readCount << endl;
|
|||
|
if (readCount > 0) {
|
|||
|
|
|||
|
push_audio_stream(audioBuf, (int)readCount);
|
|||
|
|
|||
|
usleep(125000); // 4000 bytes is 0.125 seconds of audio, sleep 0.125 seconds to simulate actual conditions if recording
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
push_audio_stream(audioBuf, 0);
|
|||
|
|
|||
|
fclose(fp);
|
|||
|
sleep(5);
|
|||
|
} else {
|
|||
|
cout << "Failed open audio file" << endl;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//用于推送录音数据
|
|||
|
void push_audio_stream(char* stream, unsigned int streamSize) {
|
|||
|
|
|||
|
int req;
|
|||
|
BDuerMessage message;
|
|||
|
message.set_name((char*) BDUER_CMD_AUDIORECORDER_PCM_STREAM_BUFFER);
|
|||
|
message.set_parameter(BDUER_PARAM_KEY_AUDIORECORDER_PCM_STREAM_DATA, (const char*) stream,
|
|||
|
streamSize);
|
|||
|
duerSDK->post(message, &req);
|
|||
|
}
|
|||
|
|
|||
|
int main(int argc, char** argv) {
|
|||
|
|
|||
|
duerSDK = BDuerSDK::get_instance();
|
|||
|
|
|||
|
ReqBack* reqBack = new ReqBack();
|
|||
|
duerSDK->set_event_lisner(reqBack);
|
|||
|
const string id = "123";
|
|||
|
duerSDK->init("dm7AC330B184803227", "23411AAB2F5A5A02C25967FE0A162BEB", "test", "");
|
|||
|
|
|||
|
while (1) {
|
|||
|
struct timeval wait = {0, 100 * 1000};
|
|||
|
::select(0, NULL, NULL, NULL, &wait);
|
|||
|
}
|
|||
|
}
|
|||
|
|