📄 voicein.c
字号:
GraphDrawText(0x10, 0x20, 0, 0, (UINT8 *)(szInfo));
//added by ju for test decode g723 data begin
sprintf((char *)szInfo, "the decode data length(bytes):%d ", g_nG723OutPutDataNum);
GraphDrawText(0x10, 0x30, 0, 0, (UINT8 *)(szInfo));
//added by ju for test decode g723 data end
return (HTIMER)&g_VoiceTimer;
}
#endif
BOOL __VoicePlay(VoiceHandle voiceHandle)
{
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
NU_DRIVER_REQUEST request;
//检查句柄是否合法
if(voiceHandle != g_VoiceHandle)
{
//既然句柄错误,回调函数也不是对的,不能发错误回调通知
// if(pVoicePlayParam->pCallBackFunc != NULL)
// ((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)(VOICE_NOTIFY_PLAY_FAIL, 0);
return FALSE;
}
if(__VoicePlayInit(pVoicePlayParam) == FALSE)
{
if(pVoicePlayParam->pCallBackFunc != NULL)
((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)(VOICE_NOTIFY_PLAY_FAIL, 0);
__VoicePlayExit(pVoicePlayParam);
return FALSE;
}
__VoicePlayOffsetAdjust(pVoicePlayParam);// 对MP3数据格式进行
//WMA文件
if(pVoicePlayParam->playType == VOICE_TYPE_WMA)
{
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"wma_headlength";
request.nu_request_info.nu_input.nu_request_size = pVoicePlayParam->dwHeadLength;
NU_Request_Driver(pVoicePlayParam->pAcmDrv, &request);
//至少要播放1秒
if(pVoicePlayParam->dwTimeLength >= 1 &&
pVoicePlayParam->dwPlayOffset >= pVoicePlayParam->dwTimeLength *
((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->nAvgBytesPerSec)
{
pVoicePlayParam->dwPlayOffset = (pVoicePlayParam->dwTimeLength - 1) *
((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->nAvgBytesPerSec;
}
}
#ifdef VOICE_TIME_TEST
__VoiceTimerCreate();
#endif
//clear hdrwave read counter
__VoiceDataReadCounterClr();
// 开始解码前两块
if(__VoiceDataRead(&hdrWave1, ACM_STREAMCONVERTF_START|ACM_STREAMCONVERTF_BLOCKALIGN) == FALSE)
{
if(pVoicePlayParam->pCallBackFunc != NULL)
((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)(VOICE_NOTIFY_PLAY_FAIL, 0);
__VoicePlayExit(pVoicePlayParam);
pVoicePlayParam->dwPlayOffset = 0;
return FALSE;
}
else
{
__VoiceDataRead(&hdrWave2, ACM_STREAMCONVERTF_BLOCKALIGN);
__VoiceDataRead(&hdrWave3, ACM_STREAMCONVERTF_BLOCKALIGN);
}
#ifdef VOICE_TIME_TEST
while(__VoiceDataRead(&hdrWave2, ACM_STREAMCONVERTF_BLOCKALIGN) == TRUE)
;
__VoiceTimerDestroy();
__VoiceFileClose(pVoicePlayParam);
while(1);
#endif
//要保证至少有一点数据可以播放
// if(pVoicePlayParam->dwPlayOffset + pVoicePlayParam->dwFrameLength > pVoicePlayParam->dwPlayEnd)
// pVoicePlayParam->dwPlayOffset = pVoicePlayParam->dwPlayEnd - pVoicePlayParam->dwFrameLength;
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"play";
if ( NU_Request_Driver(pVoicePlayParam->pAudioDrv, &request) != MMSYSERR_NOERROR)
{
__VoicePlayExit(pVoicePlayParam);
pVoicePlayParam->dwPlayOffset = 0;
if(pVoicePlayParam->pCallBackFunc != NULL)
((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)(VOICE_NOTIFY_PLAY_FAIL, 0);
return FALSE;
}
TimStartTimer(g_hVoiceTimer);
//记录当前状态
g_VoiceStatus = VOICE_STATUS_PLAY;
return TRUE;
}
BOOL __VoicePause(VoiceHandle voiceHandle)
{
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
NU_DRIVER_REQUEST request;
//检查句柄是否合法
if(voiceHandle != g_VoiceHandle)
return FALSE;
if(g_VoiceStatus != VOICE_STATUS_PLAY)
return FALSE;
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"pause";
NU_Request_Driver(pVoicePlayParam->pAudioDrv, &request);
TimStopTimer(g_hVoiceTimer);
g_VoiceStatus = VOICE_STATUS_PLAYPAUSE;
return TRUE;
}
BOOL __VoiceResume(VoiceHandle voiceHandle)
{
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
NU_DRIVER_REQUEST request;
//检查句柄是否合法
if(voiceHandle != g_VoiceHandle)
return FALSE;
if(g_VoiceStatus != VOICE_STATUS_PLAYPAUSE)
return FALSE;
if(hdrWave1.dwUser == WAVEHDR_NOT_USE)
{
__VoiceDataRead(&hdrWave1, ACM_STREAMCONVERTF_BLOCKALIGN);
}
if(hdrWave2.dwUser == WAVEHDR_NOT_USE)
{
__VoiceDataRead(&hdrWave2, ACM_STREAMCONVERTF_BLOCKALIGN);
}
if(hdrWave3.dwUser == WAVEHDR_NOT_USE)
{
__VoiceDataRead(&hdrWave3, ACM_STREAMCONVERTF_BLOCKALIGN);
}
//clear hdrwave read counter
__VoiceDataReadCounterClr();
//两个Buffer都没有数据,返回失败
if(hdrWave1.dwUser == WAVEHDR_NOT_USE &&
hdrWave2.dwUser == WAVEHDR_NOT_USE &&
hdrWave3.dwUser == WAVEHDR_NOT_USE)
return FALSE;
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"resume";
if ( NU_Request_Driver(pVoicePlayParam->pAudioDrv, &request) != MMSYSERR_NOERROR)
return FALSE;
TimStartTimer(g_hVoiceTimer);
g_VoiceStatus = VOICE_STATUS_PLAY;
return TRUE;
}
BOOL __VoicePlayStop(VoiceHandle voiceHandle)
{
// MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
//检查句柄是否合法
if(voiceHandle != g_VoiceHandle)
return FALSE;
__VoiceStop(VOICE_NOTIFY_NONE);
return TRUE;
}
BOOL __VoiceClose(VoiceHandle voiceHandle)
{
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
//检查句柄是否合法
if(voiceHandle != g_VoiceHandle)
return FALSE;
__VoiceStop(VOICE_NOTIFY_NONE);
__VoiceFileClose(pVoicePlayParam);
g_VoiceHandle |= VOICE_HANDLE_MASK;
return TRUE;
}
/****************************************************************************/
/* FUNCTION: __VoiceStop */
/* DESCRIPTION:打断当前的录放音 */
/* INPUTS: UINT8 - bStopType: 停止类型 */
/* OUTPUTS: NONE */
/* RETURN: TRUE / FALSE */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* HuangXM 2003-06-19 创建 */
/****************************************************************************/
BOOL __VoiceStop(UINT8 bStopType)
{
VOICECALLBACKPROC pCallBack;
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
MVoiceRecordParam* pVoiceRecordParam = &g_VoiceRecordParam;
NU_DRIVER_REQUEST request;
TimStopTimer(g_hVoiceTimer);
//Clear wave header use flag
hdrWave1.dwUser = WAVEHDR_NOT_USE;
hdrWave2.dwUser = WAVEHDR_NOT_USE;
hdrWave3.dwUser = WAVEHDR_NOT_USE;
//当前在放音
if((g_VoiceStatus == VOICE_STATUS_PLAY)
|| (g_VoiceStatus == VOICE_STATUS_PLAYPAUSE))
{
__VoiceCheck(pVoicePlayParam);
//先将状态改为停止,防止文件关闭内存释放后还有读写操作
g_VoiceStatus = VOICE_STATUS_STOP;
request.nu_function = NU_STATUS;
if(bStopType == VOICE_NOTIFY_FINISH)
request.nu_supplemental_ptr = (VOID *)"finish";
else
request.nu_supplemental_ptr = (VOID *)"stop";
NU_Request_Driver(g_VoicePlayParam.pAudioDrv, &request);
__VoicePlayExit(pVoicePlayParam);
//回调通知放音被打断
if(pVoicePlayParam->pCallBackFunc != NULL)
{
pCallBack = (VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc;
if(bStopType == VOICE_NOTIFY_STOP || bStopType == VOICE_NOTIFY_FINISH)
pCallBack(VOICE_NOTIFY_PLAY_STOP, g_VoiceHandle);
else if(bStopType == VOICE_NOTIFY_BREAK)
pCallBack(VOICE_NOTIFY_PLAY_BREAK, g_VoiceHandle);
}
}
//当前在录音
else if((g_VoiceStatus == VOICE_STATUS_RECORD)
|| (g_VoiceStatus == VOICE_STATUS_RECORDPAUSE))
{
//先将状态改为停止,防止文件关闭内存释放后还有读写操作
g_VoiceStatus = VOICE_STATUS_STOP;
//回调通知录音被打断
if(pVoiceRecordParam->pCallBackFunc != NULL)
{
pCallBack = (VOICECALLBACKPROC)pVoiceRecordParam->pCallBackFunc;
if(bStopType == VOICE_NOTIFY_STOP || bStopType == VOICE_NOTIFY_FINISH)
pCallBack(VOICE_NOTIFY_RECORD_STOP, pVoiceRecordParam->dwRecordOffset);
else if(bStopType == VOICE_NOTIFY_BREAK)
pCallBack(VOICE_NOTIFY_RECORD_BREAK, pVoiceRecordParam->dwRecordOffset);
}
// g_VoicePlayFunc[pVoiceRecordParam->recordType].pVoiceDrvFunc->VoiceRecordStop(pVoiceRecordParam);
}
//当前播放停止,只要句柄有效,也要回调通知
else if((g_VoiceStatus == VOICE_STATUS_STOP) && ((g_VoiceHandle & VOICE_HANDLE_MASK) == 0))
{
//回调通知放音被打断
if((bStopType == VOICE_NOTIFY_BREAK) && (pVoicePlayParam->pCallBackFunc != NULL))
{
pCallBack = (VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc;
pCallBack(VOICE_NOTIFY_PLAY_BREAK, g_VoiceHandle);
}
}
if(bStopType == VOICE_NOTIFY_BREAK)
{
__VoiceFileClose(pVoicePlayParam);
g_VoiceHandle |= VOICE_HANDLE_MASK;
}
g_VoiceStatus = VOICE_STATUS_STOP;
return TRUE;
}
/****************************************************************************/
/* FUNCTION: __VoiceDataWrite */
/* DESCRIPTION:Adi数据输入处理 */
/* INPUTS: NONE */
/* OUTPUTS: NONE */
/* RETURN: TRUE / FALSE */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* HuangXM 2003-06-19 创建 */
/****************************************************************************/
BOOL __VoiceDataWrite()
{
/* MVoiceRecordParam* pVoiceRecordParam = &g_VoiceRecordParam;
pVoiceRecordParam->pBuffer = NULL;
pVoiceRecordParam->dwBufferSize = 0;
while(1)
{
if(g_VoicePlayFunc[pVoiceRecordParam->recordType].pVoiceDrvFunc->VoiceRecordGetData(pVoiceRecordParam)
!= g_VoicePlayFunc[pVoiceRecordParam->recordType].pVoiceDrvFunc->voiceSuccess)
break;
if(pVoiceRecordParam->dwBufferSize == 0)
break;
if(pVoiceRecordParam->dwRecordOffset + pVoiceRecordParam->dwBufferSize > pVoiceRecordParam->dwBufLength)
{
VOICECALLBACKPROC pCallBackFunc;
pCallBackFunc = (VOICECALLBACKPROC)pVoiceRecordParam->pCallBackFunc;
pCallBackFunc(VOICE_NOTIFY_RECORD_FULL, (UINT32)pVoiceRecordParam);
}
if(pVoiceRecordParam->dwRecordOffset + pVoiceRecordParam->dwBufferSize > pVoiceRecordParam->dwBufLength)
return __VoiceStop(VOICE_NOTIFY_STOP);
memcpy(&pVoiceRecordParam->pRecordBuf[pVoiceRecordParam->dwRecordOffset],
pVoiceRecordParam->pBuffer, pVoiceRecordParam->dwBufferSize);
pVoiceRecordParam->dwRecordOffset += pVoiceRecordParam->dwBufferSize;
}
*/
return TRUE;
}
VOID *__VoiceMemAlloc(MVoicePlayParam* pVoicePlayParam, UINT32 dwSize)
{
if(pVoicePlayParam->playMode & VOICE_MODE_BACKGROUND)
return MemAllocEx(dwSize);
else
return MemAlloc(dwSize);
}
BOOL __VoiceProtect()
{
g_VoicePreemptStatus = NU_Change_Preemption(NU_NO_PREEMPT);
return TRUE;
}
BOOL __VoiceUnprotect()
{
NU_Change_Preemption(g_VoicePreemptStatus);
return TRUE;
}
VOID __VoiceDataReadCounterClr(VOID)
{
hdrWave1.reserved = 0;
hdrWave2.reserved = 0;
hdrWave3.reserved = 0;
g_dwHdrWavCounter = 0;
}
BOOL __VoiceDataReadCheck(WAVEHDR *pwh)
{
// Dennyhan added: for PC playing
#ifndef _WIN32
/*if(pwh->reserved == g_dwHdrWavCounter / 3 ||
pwh->reserved == g_dwHdrWavCounter / 3 + 1)
{
pwh->reserved ++;
g_dwHdrWavCounter ++;
return TRUE;
}
else
return FALSE;*/ //zjj delete
return TRUE;
#else
return TRUE;
#endif
}
BOOL WmaFileSetOffset(UINT32 dwOffset)
{
NU_DRIVER *pWmaDecDrv;
NU_DRIVER_REQUEST request;
pWmaDecDrv = GetIODriverFromName((UINT8*)DRV_NAME_ACM_WMA);
if(pWmaDecDrv == NULL)
return FALSE;
//get wma head info
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"wma_setoffset";
request.nu_request_info.nu_input.nu_request_size = dwOffset;
NU_Request_Driver(pWmaDecDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR)
return FALSE;
return TRUE;
}
UINT32 WmaFileGetOffset(VOID)
{
NU_DRIVER *pWmaDecDrv;
NU_DRIVER_REQUEST request;
pWmaDecDrv = GetIODriverFromName((UINT8*)DRV_NAME_ACM_WMA);
if(pWmaDecDrv == NULL)
return FALSE;
//get wma head info
request.nu_function = NU_STATUS;
request.nu_supplemental_ptr = (VOID *)"wma_getoffset";
NU_Request_Driver(pWmaDecDrv, &request);
if (request.nu_status != MMSYSERR_NOERROR)
return FALSE;
return request.nu_request_info.nu_input.nu_actual_size;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -