// //#define CPP_DLL_API __declspec(dllexport) #include #include #include #include #include #include #include #include #include #include #include #include #include #include "RecognitionCppDll.h" #pragma comment(lib, "ws2_32" ) #pragma comment(lib, "pthreadVC2.lib") #pragma comment(lib, "vsdllsdk6.lib") //extern std::string gTtsStrGlobal; //extern std::string gSdkConfigBasePath; //extern std::vector gWaveData; //extern volatile bool gFinishRecording; //extern std::string GBKToUTF8(const std::string& strGBK); extern std::string GBKToUTF8(const std::string& strGBK); extern std::string UTF8ToGBK(const char* strUTF8); std::string gTtsStrGlobal=""; std::string gSdkConfigBasePath = "D:\\sdktest\\config"; std::vector gWaveData; volatile bool gFinishRecording = false; std::mutex gMutex; std::condition_variable gCondition; pthread_mutex_t gPMutex; pthread_cond_t gPCondition; //extern "C" int recordAndSaveWav(); extern int recordAndSaveWav(); #define INSTANT_RECORD_DATA 1 #define VECTOR_SIZE 640 * 1000 //20ms--640k, 20s--1000*640 namespace mobvoi { namespace sds { class OnlineRecognizerDemo::RecognizerCallBack : public CallBackBase { public: explicit RecognizerCallBack(OnlineRecognizerDemo* recognizer) : recognizer_(recognizer) {} virtual void CallBack(const Parameter& param) { std::string cb_type = param[MOBVOI_SDS_CB_TYPE].AsString(); std::string cb_typeDisp= UTF8ToGBK(cb_type.c_str()); int cb_ec = 0; std::string cb_info; std::string cb_info_temp; if (param.HasParam(MOBVOI_SDS_ERROR_CODE)) { cb_ec = param[MOBVOI_SDS_ERROR_CODE].AsInt(); } gTtsStrGlobal = ""; if (param.HasParam(MOBVOI_SDS_CB_INFO)) { //cb_info = param[MOBVOI_SDS_CB_INFO].AsString(); cb_info_temp = param[MOBVOI_SDS_CB_INFO].AsString(); cb_info = UTF8ToGBK(cb_info_temp.c_str()); } std::cerr << "RecognizerCallBack::CallBack() invoked: type:" << cb_typeDisp.c_str()<<" info:" << cb_info<< std::endl << std::flush; //std::cerr << param << std::endl; /////////type////// if (MOBVOI_SDS_CB_ERROR == cb_type) { gFinishRecording = true; std::cout << "识别异常, 错误码是: " << cb_ec << std::endl; std::string temp1; std::stringstream ss; ss << cb_ec; ss >> temp1; std::string temp2 = cb_typeDisp + ": " + temp1; recognizer_->callCSharp(-1, cb_typeDisp.c_str(), temp2.c_str()); //recognizer_->callCSharp(1, cb_typeDisp.c_str()); recognizer_->Notify(); } else if (MOBVOI_SDS_CB_FINAL_TRANSCRIPT == cb_type) { gFinishRecording = true; std::cout << "语音识别结果: " << cb_info << std::endl; recognizer_->callCSharp(0, cb_typeDisp.c_str(), cb_info.c_str()); } else if (MOBVOI_SDS_CB_PARTIAL_TRANSCRIPT == cb_type) { gFinishRecording = false; std::cout << std::endl; std::cout << "中间识别结果: " << cb_info << std::endl; recognizer_->callCSharp(0, cb_typeDisp.c_str(),cb_info.c_str()); } else if (MOBVOI_SDS_CB_REMOTE_SILENCE == cb_type) { //gFinishRecording = true; std::cout << "检测不到声音了:" << std::endl; //recognizer_->callCSharp(0, cb_typeDisp.c_str(), "silence detected"); } else if (MOBVOI_SDS_CB_RESULT == cb_type) { gFinishRecording = true; std::cout << std::endl; std::cout << "语义分析查询结果: " << cb_info << std::endl; //播放displayText内容 gTtsStrGlobal = ""; int index = cb_info_temp.find("displayText"); if (index > 0) { int start = index + 14; int len = cb_info_temp.length() - index - 15; std::string sub1 = cb_info_temp.substr(start, len); index = sub1.find("\",\""); if (index > 0) { std::string sub2 = sub1.substr(0, index); //if (sub2.length() > 200) { // gTtsStrGlobal = sub2.substr(0, 200); //} //else { gTtsStrGlobal = sub2; //} } } if (gTtsStrGlobal == "") { std::string temp = "未找到合适的查询结果";//以.结束 gTtsStrGlobal = GBKToUTF8(temp); } // recognizer_->callCSharp(0, cb_typeDisp.c_str(),cb_info.c_str()); recognizer_->Notify(); } else if (MOBVOI_SDS_CB_NLU == cb_type) { gFinishRecording = true; std::cout << "MOBVOI_SDS_CB_NLU: " << cb_info << std::endl; } else if (MOBVOI_SDS_CB_VOLUME == cb_type) { gFinishRecording = false; std::cout << "MOBVOI_SDS_CB_VOLUME: " << cb_info << std::endl; } else { gFinishRecording = true; std::cerr << "Error: Unknown callback type " << cb_type << std::endl; //recognizer_->callCSharp(3, "Unknown error"); recognizer_->callCSharp(-1, cb_typeDisp.c_str(),cb_typeDisp.c_str()); recognizer_->Notify();//// } } OnlineRecognizerDemo* recognizer_; //private: }; #ifdef UNICODE std::string tchar2string(TCHAR *STR) { int iLen = WideCharToMultiByte(CP_ACP, 0, STR, -1, NULL, 0, NULL, NULL); char* chRtn = new char[iLen * sizeof(char)]; WideCharToMultiByte(CP_ACP, 0, STR, -1, chRtn, iLen, NULL, NULL); std::string str(chRtn); delete chRtn; return str; } #endif std::string getCurrentDir() { TCHAR currentPath[MAX_PATH]; // Full path GetCurrentDirectory(MAX_PATH, currentPath); #ifdef UNICODE return tchar2string(currentPath); #else return currentPath; #endif } OnlineRecognizerDemo::OnlineRecognizerDemo() : service_(nullptr), service_type_(""), stop_(false), enablePartial_(false), mutex_(PTHREAD_MUTEX_INITIALIZER), cond_(PTHREAD_COND_INITIALIZER), sds_(nullptr) { sds_ = SpeechSDS::MakeInstance(); gSdkConfigBasePath = getCurrentDir() + "\\config"; WSADATA data; if (WSAStartup(MAKEWORD(1, 1), &data) != 0) { std::cerr << "Could not initialise Winsock:" << stderr << std::endl; } gWaveData.reserve(VECTOR_SIZE); } OnlineRecognizerDemo::~OnlineRecognizerDemo() { pthread_mutex_destroy(&mutex_); pthread_cond_destroy(&cond_); SpeechSDS::DestroyInstance(sds_); WSACleanup(); } void RecordTask() { recordAndSaveWav(); } void OnlineRecognizerDemo::setRecognitionParams(bool enablePartial) { enablePartial_ = enablePartial; std::cerr << "setRecognitionParams:" << enablePartial_ << std::endl; } bool OnlineRecognizerDemo::startRecognition() { bool res = false; gWaveData.clear(); gFinishRecording = false; std::thread recorderThread(RecordTask); Sleep(100); //recordAndSaveWav(); res = Run(0, NULL); if (recorderThread.joinable()) { recorderThread.join(); } std::cerr << "Recognition finished" << std::endl; pCallback->recognizer_ = NULL; return res; } bool OnlineRecognizerDemo::startRecognition(void* Function) { cSharpCallback = (ResultCallbackType)(Function); bool res = startRecognition(); return res; } void OnlineRecognizerDemo::callCSharp(int code, const char * type, const char * info ) { if (cSharpCallback != nullptr) { std::cerr << " code:" << code <<" type:"<Init(params); } bool OnlineRecognizerDemo::GetService() { service_ = sds_->GetService(service_type_); return (service_ != nullptr); } bool OnlineRecognizerDemo::InvokeService() { bool res1 = InvokeSetParamService(); bool res2 = InvokeStartService(); bool res3 = InvokeFeedSpeech(); bool res4 = InvokeStopService(); return (res1 && res2 && res3 && res4); } bool OnlineRecognizerDemo::InvokeSetParamService() { Parameter params(MOBVOI_SDS_SET_PARAM); static RecognizerCallBack callback(NULL); pCallback = &callback; pCallback->recognizer_ = this; params[MOBVOI_SDS_CALLBACK] = &callback; //params[MOBVOI_SDS_REMOTE_START_SILENCE] = 5000; //params[MOBVOI_SDS_REMOTE_END_SILENCE] = 1000; //params[MOBVOI_SDS_ENABLE_CB_PARTIAL] = true; //params[MOBVOI_SDS_ENABLE_CB_VOLUME] = false; params[MOBVOI_SDS_REMOTE_START_SILENCE] = 5000; params[MOBVOI_SDS_REMOTE_END_SILENCE] = 1000; std::cerr << "InvokeSetParamService setRecognitionParams:" << enablePartial_ << std::endl; params[MOBVOI_SDS_ENABLE_CB_PARTIAL] = enablePartial_; params[MOBVOI_SDS_ENABLE_CB_VOLUME] = false; Parameter result = service_->Invoke(params); if (result[MOBVOI_SDS_ERROR_CODE].AsInt() != MOBVOI_SDS_SUCCESS) { std::cerr << "Set parameter error: " << result[MOBVOI_SDS_ERROR_CODE].AsInt() << std::endl; gTtsStrGlobal = "设置参数失败"; callCSharp(-1, "SDK_INIT_ERROR", "设置参数失败"); return false; } return true; } bool OnlineRecognizerDemo::InvokeStartService() { Parameter params(MOBVOI_SDS_START); Parameter result = service_->Invoke(params); if (result[MOBVOI_SDS_ERROR_CODE].AsInt() != MOBVOI_SDS_SUCCESS) { std::cerr << "Start error: " << result[MOBVOI_SDS_ERROR_CODE].AsInt() << std::endl; gTtsStrGlobal = "启动识别失败,授权可能过期"; callCSharp(-1, "SDK_INIT_ERROR", "MOBVOI_SDS_START失败,license可能过期了"); return false; } return true; } bool OnlineRecognizerDemo::InvokeFeedSpeech() { Parameter params(MOBVOI_SDS_FEED_SPEECH); const int kBatchSize = 640; const int kSleepTime =10 * 1000; gPMutex = PTHREAD_MUTEX_INITIALIZER; gPCondition = PTHREAD_COND_INITIALIZER; size_t pos = 0; //size_t length = waves_.size(); //auto* start = &waves_[0]; size_t length = gWaveData.size(); char* start = NULL; if (length > 0) { start = &gWaveData[0]; } while ((pos < length)/* && (!gFinishRecording)*/ ) { pthread_mutex_lock(&mutex_); if (stop_) { pthread_mutex_unlock(&mutex_); break; } pthread_mutex_unlock(&mutex_); size_t stride = (pos + kBatchSize < length) ? kBatchSize : (length - pos); Buf audio_buf(start + pos, stride); params[MOBVOI_SDS_AUDIO_BUF] = audio_buf; Parameter result = service_->Invoke(params); if (result[MOBVOI_SDS_ERROR_CODE].AsInt() != MOBVOI_SDS_SUCCESS) { std::cerr << "Error: service->Invoke: " << result[MOBVOI_SDS_ERROR_CODE].AsInt() << std::endl; return false; } //std::this_thread::sleep_for(std::chrono::milliseconds(kSleepTime / 1000)); if (!gFinishRecording) { std::unique_lock lock(gMutex); gCondition.wait(lock); lock.unlock(); } /* while (!gFinishRecording) { std::unique_lock lock(gMutex); size_t lengthTemp = gWaveData.size(); if (lengthTemp - length < 640) { gCondition.wait(lock); } else { break; lock.unlock(); } lock.unlock(); } if (!gFinishRecording) { std::unique_lock lock(gMutex); gCondition.wait(lock); lock.unlock(); } pthread_mutex_lock(&gPMutex); if (!gFinishRecording) { pthread_cond_wait(&gPCondition, &gPMutex); } pthread_mutex_unlock(&gPMutex); */ length = gWaveData.size(); pos += stride; } return true; } bool OnlineRecognizerDemo::InvokeStopService() { Parameter params(MOBVOI_SDS_STOP); Parameter result = service_->Invoke(params); if (result[MOBVOI_SDS_ERROR_CODE].AsInt() != MOBVOI_SDS_SUCCESS) { std::cerr << "Invoke SDS_ASR_STOP error: " << result[MOBVOI_SDS_ERROR_CODE].AsInt() << std::endl; return false; } return true; } bool OnlineRecognizerDemo::ReleaseService() { pthread_mutex_lock(&mutex_); if (!stop_) { pthread_cond_wait(&cond_, &mutex_); } pthread_mutex_unlock(&mutex_); if (sds_->ReleaseService(service_)) { service_ = nullptr; return true; } else { std::cout << "Failed releasing service " << service_type_ << std::endl; } return false; } bool OnlineRecognizerDemo::ReleaseEnv() { return sds_->CleanUp(); } void OnlineRecognizerDemo::ShowUsage(const std::string& exe) { std::cerr << "Usage: "<< std::endl; } } // namespace sds } // namespace mobvoi