#include "caudiotransmission.h" #include "..\\..\\Other\\libaudiotransqueue\\libaudiotransqueue.h" Caudiotransmission::Caudiotransmission(asr_server_info_t* pAsrServerInfo) { LOG_FUNCTION(); if (0 == InitAudioTransmission()){ m_hEventStop= ::CreateEventA(NULL, TRUE, FALSE, 0); if (NULL == m_hEventStop) { Dbg("create m_hEventStop failed!"); } if (NULL != pAsrServerInfo){ sprintf_s(m_strMainServerURL, MAX_PATH, "%s", pAsrServerInfo->strMainServerURL); sprintf_s(m_strBackupServerURL, MAX_PATH, "%s", pAsrServerInfo->strBackupServerURL); if (NULL != pAsrServerInfo->fCreateObj){ m_fCreateObj = pAsrServerInfo->fCreateObj; m_pIAudioTransObj = m_fCreateObj(); if (NULL != m_pIAudioTransObj){ Dbg("create audio transmission object success!"); } } m_fDestoryObj = pAsrServerInfo->fDestoryObj; m_iTimeOut = pAsrServerInfo->iTimeOut; m_iMaxAudioSize = pAsrServerInfo->iMaxAudioSize; Dbg("init cpp restful success, connect timeout time is %d, max audio send size is %d.",m_iTimeOut, m_iMaxAudioSize); } } } int Caudiotransmission::InitAudioTransmission() { LOG_FUNCTION(); int iRet = -1; memset(m_AudioQueueName, 0, MAX_PATH); memset(m_strMainServerURL, 0, MAX_PATH); memset(m_strBackupServerURL, 0, MAX_PATH); m_pIAudioTransObj = NULL; m_iTimeOut = DEFAULT_CONNECT_TIMEOUT; m_iMaxAudioSize = DEFAULT_MAX_AUDIO_SEND_SIZE; m_fCreateObj = NULL; m_fDestoryObj = NULL; m_salestransaudioqueue = NULL; m_hEventStop = NULL; m_hAudioTransThread = NULL; m_nAudioTransThreadId = 0; iRet = 0; return iRet; } void Caudiotransmission::HandleAudioTransException() { LOG_FUNCTION(); Dbg("音频流传输失败."); LogEvent(Severity_High, LOG_EVT_AUDIOSTREAM_TRANSMISSION_FAILED, "音频流传输失败."); if (NULL != m_salestransaudioqueue) { if (m_salestransaudioqueue->ClearQueue()) { Dbg("clear audio transmission queue success."); } Dbg("delete sales trans audio queue, and it's addr is %0x.", m_salestransaudioqueue); delete m_salestransaudioqueue; m_salestransaudioqueue = NULL; } } eAudioFrameFlag Caudiotransmission::TansferAudioBlockFlag(eAudioFrameFlag eFlag) { eAudioFrameFlag eAudioFrameType = eAudioFrameComplete; if (eAudioFrameComplete != eFlag) { if (eAudioFrameInit == eFlag) { eAudioFrameType = eAudioFrameFirst; } else { eAudioFrameType = eAudioFrameCountinue; } } return eAudioFrameType; } int Caudiotransmission::AudioTransmissionThreadFunc() { LOG_FUNCTION(); int iRet = -1; int iAudioWriteFailedCount = 0; bool bStopRecord = false; int iSendNum = 0; int iLastCopySeriNum = 0; audio_frame* audioframe = new audio_frame; memset(audioframe, 0, sizeof(audio_frame)); eAudioFrameFlag eAudioFrameType = eAudioFrameInit; unsigned char audiodata[SINGLE_AUDIO_FRAME_SIZE] = {0}; int iCopyBufferLen = 0; unsigned char* pSendBuffer = new unsigned char[m_iMaxAudioSize]; memset(pSendBuffer, 0, m_iMaxAudioSize); while(true){ DWORD dwRet = WaitForSingleObject(m_hEventStop, AUDIO_TRANS_INTERVAL_TIME); if (WAIT_OBJECT_0 == dwRet) { Dbg("exit circle for set event true."); bStopRecord = true; } if (NULL != m_salestransaudioqueue) { int nAudioLens = m_salestransaudioqueue->Count(); Dbg("current sales trans audio queue length is %d.", nAudioLens); if (nAudioLens > 0){ audioframe->data = (char*)audiodata; if (true == m_salestransaudioqueue->TryDequeue(audioframe)){ if (false == m_salestransaudioqueue->DeleteQueueHead()){ Dbg("sales trans audio queue delete head failed."); } if (iLastCopySeriNum == audioframe->iseriesnumber){ Dbg("audio series number is %d has been succeed memcpy.", audioframe->iseriesnumber); continue; } memcpy((unsigned char*)pSendBuffer+iCopyBufferLen, audiodata, audioframe->framesize); iCopyBufferLen += SINGLE_AUDIO_FRAME_SIZE; iLastCopySeriNum = audioframe->iseriesnumber; Dbg("current memcpy audio series number is %d.",iLastCopySeriNum); } else{ Dbg("sales trans audio queue length is not zero,try get audio from queue failed, continue."); continue; } }else{ if (true != bStopRecord){ Dbg("sales trans audio queue length is 0,and not stop record, continue."); Sleep(200); continue; } else{ Dbg("bStopRecord is true and audio length is zero set audio frame eAudioFrameComplete,last buffer len is not %d.",m_iMaxAudioSize); eAudioFrameType = eAudioFrameComplete; if (0 == iCopyBufferLen){ memcpy((unsigned char*)pSendBuffer, audiodata, SINGLE_AUDIO_FRAME_SIZE); iCopyBufferLen += SINGLE_AUDIO_FRAME_SIZE; } } } if (iCopyBufferLen < m_iMaxAudioSize){ if (eAudioFrameComplete!= eAudioFrameType){ continue; } } else{ if (bStopRecord && 0 == m_salestransaudioqueue->Count()){ Dbg("bStopRecord is true and audio length is zero set audio frame eAudioFrameComplete, last buffer len is %d.", m_iMaxAudioSize); eAudioFrameType = eAudioFrameComplete; } } if (NULL != m_pIAudioTransObj){ eAudioFrameType = TansferAudioBlockFlag(eAudioFrameType); if (0 == m_pIAudioTransObj->SessionAudioWrite(pSendBuffer, iCopyBufferLen, eAudioFrameType, ++iSendNum)){ Dbg("success write audio number is %d, send buffer len is %d, and audio frame type is %d.", iSendNum, iCopyBufferLen, eAudioFrameType); if (0 != iAudioWriteFailedCount){ iAudioWriteFailedCount = 0; } } else{ Dbg("audio write failed, audio block series number is %d, current block len is %d, and audio frame type is %d.", iSendNum, iCopyBufferLen, eAudioFrameType); iAudioWriteFailedCount++; if (iAudioWriteFailedCount > MAX_TRANSFAILED_COUNT){ HandleAudioTransException(); Dbg("more than %d time audio write failed, break.", MAX_TRANSFAILED_COUNT); break; } } } memset(pSendBuffer, 0, m_iMaxAudioSize); iCopyBufferLen = 0; } else{ eAudioFrameType = eAudioFrameComplete; } if (eAudioFrameComplete == eAudioFrameType){ Dbg("break"); break; } } delete audioframe; audioframe = NULL; if (NULL != pSendBuffer){ delete []pSendBuffer; pSendBuffer = NULL; } return iRet; } //音频包传输到AI识别服务器线程 static unsigned int __stdcall AudioTransThread(LPVOID pPram) { LOG_FUNCTION(); Caudiotransmission* pAudioTrans = (Caudiotransmission*)pPram; int iRet = -1; //__try { iRet = pAudioTrans->AudioTransmissionThreadFunc(); } //__except(wmvrecorddump_exception(GetExceptionInformation(),WmvRecord), EXCEPTION_EXECUTE_HANDLER) { //} return iRet; } int Caudiotransmission::StartAudioTransmission(const char* strAudioQueue, void* pBlob, size_t uLen) { LOG_FUNCTION(); int iRet = -1; if (NULL != strAudioQueue){ sprintf_s(m_AudioQueueName, MAX_PATH, "%s", strAudioQueue); } Dbg("audio queue name is %s.", m_AudioQueueName); m_salestransaudioqueue = new Clibaudiotransqueue(m_AudioQueueName); if (NULL != m_salestransaudioqueue){ Dbg("get sales trans audio queue success, and queue addr is %0x.", m_salestransaudioqueue); } //session create if (NULL != m_pIAudioTransObj){ Dbg("m_strMainServerURL is %s.", m_strMainServerURL); iRet = m_pIAudioTransObj->SessionCreate(m_strMainServerURL, m_iTimeOut); if (0 != iRet){ Dbg("session create failed!"); return iRet; } else{ Dbg("session create success!"); } } else{ Dbg("audio trans object is not valid."); return iRet; } //session begin if (NULL != pBlob){ iRet = m_pIAudioTransObj->SessionBegin(pBlob, uLen); } else{ Dbg("invalid session begin params."); return iRet; } if (0 != iRet){ Dbg("session begin failed!"); } else{ Dbg("session begin success, and start audio transmission thread."); //启动音频包转发线程 ResetEvent(m_hEventStop); m_hAudioTransThread = (HANDLE)_beginthreadex(NULL, 0, AudioTransThread, (LPVOID)this, 0, (unsigned int*)& m_nAudioTransThreadId); } return iRet; } int Caudiotransmission::StopAudioTransmission() { LOG_FUNCTION(); int iRet = -1; SetEvent(m_hEventStop); WaitForSingleObject(m_hAudioTransThread, INFINITE); CloseHandle(m_hAudioTransThread); m_hAudioTransThread = NULL; if (NULL != m_pIAudioTransObj) { iRet = m_pIAudioTransObj->SessionEnd(); } if (NULL != m_salestransaudioqueue) { Dbg("delete sales audio trans queue."); delete m_salestransaudioqueue; m_salestransaudioqueue = NULL; } else { Dbg("sales audio trans queue is null."); } return iRet; } Caudiotransmission::~Caudiotransmission() { LOG_FUNCTION(); if (NULL != m_salestransaudioqueue){ Dbg("delete sales audio trans queue."); delete m_salestransaudioqueue; m_salestransaudioqueue = NULL; } else { Dbg("sales audio trans queue is null."); } if (NULL != m_pIAudioTransObj){ if (NULL != m_fDestoryObj){ m_fDestoryObj(m_pIAudioTransObj); Dbg("delete audio trans object."); } else { Dbg("m_fDestoryObj interface is null."); } } else { Dbg("audio trans obj is null."); } return; }