📄 voicein.c
字号:
#define ADJUST_BUF_LEN 0x300 //Global region is limited
#else
#define ADJUST_BUF_LEN 0x400
#endif
UINT8 g_AdjustBuf[ADJUST_BUF_LEN];
VOID __VoicePlayOffsetAdjust(MVoicePlayParam *pVoicePlayParam)
{
#ifdef _WIN32
return;
#else
UINT32 dwReadLen, i;
if(((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->wFormatTag != WAVE_FORMAT_MPEGLAYER3)
return;
dwReadLen = pVoicePlayParam->dwPlayOffset + 2;
if(dwReadLen > ADJUST_BUF_LEN)
dwReadLen = ADJUST_BUF_LEN;
pVoicePlayParam->dwPlayOffset -= (dwReadLen - 2);
MediaFileSeek(pVoicePlayParam->hMediaFile, pVoicePlayParam->dwPlayOffset + pVoicePlayParam->dwHeadLength, 0);
if(MediaFileRead(pVoicePlayParam->hMediaFile, g_AdjustBuf, dwReadLen) != (INT32)dwReadLen)
return;
for(i = dwReadLen; i >= 2; i --)
{
if(READ_WORD(&g_AdjustBuf[i - 2]) == ((MPEGLAYER3WAVEFORMAT *)pVoicePlayParam->wfx_buf)->wID)
{
pVoicePlayParam->dwPlayOffset += (i - 2);
return;
}
}
return;
#endif
}
BOOL __VoiceDataRead(WAVEHDR *pwh, UINT32 dwFlag)
{
NU_DRIVER_REQUEST request;
MVoicePlayParam *pVoicePlayParam;
ACMSTREAMHEADER acmHeader;
pVoicePlayParam = &g_VoicePlayParam;
__VoiceCheck(pVoicePlayParam);
if((pwh == &hdrWave1) || (pwh == &hdrWave2) || (pwh == &hdrWave3))
{
// pwh->dwUser = WAVEHDR_NOT_USE; //
pwh->dwBufferLength = pVoicePlayParam->dwDstBufferSize;
//虽然文件读完了,但是解码buffer里可能还有数据
//以前被屏蔽掉,现在重新打开 ju added begin
/* if(pVoicePlayParam->dwPlayEnd == pVoicePlayParam->dwPlayOffset)
{
if(pVoicePlayParam->pAcmDrv != NULL || g_VoiceReadEmpty == 0)
pwh->dwBufferLength = 0;
else
{
memset(pwh->lpData, 0, pwh->dwBufferLength);
g_VoiceReadEmpty ++;
}
}
else *///以前被屏蔽掉,现在重新打开 ju added end
{
g_VoiceReadEmpty = 0;
if(pVoicePlayParam->pAcmDrv == NULL)
pwh->dwBufferLength = __VoiceFileDataRead((UINT32)pVoicePlayParam,
(BYTE *)pwh->lpData, pVoicePlayParam->dwPlayOffset, pwh->dwBufferLength);
else
{
// if(dwFlag & ACM_STREAMCONVERTF_START)
acmHeader.cbStruct = sizeof(ACMSTREAMHEADER);
acmHeader.cbSrcLength = 0;//__VoiceFileDataRead(pVoicePlayParam, pVoicePlayParam->pSrcBuffer, pVoicePlayParam->dwSrcBufferSize);//pwh->dwBufferLength);
acmHeader.cbDstLength = pVoicePlayParam->dwDstBufferSize;
acmHeader.cbSrcLengthUsed = 0;
acmHeader.cbDstLengthUsed = 0;
acmHeader.pbSrc = (UINT8 *)__VoiceFileDataRead;
acmHeader.dwSrcUser = (UINT32)pVoicePlayParam;
acmHeader.cbSrcLengthUsed = pVoicePlayParam->dwPlayOffset;
acmHeader.pbDst = pwh->lpData;
AcmStreamConvert((HACMSTREAM)pVoicePlayParam->pAcmDrv, &acmHeader, dwFlag);
pwh->dwBufferLength = acmHeader.cbDstLengthUsed;
//added by ju for test decode g723 data begin
#ifdef VOICE_TIME_TEST
g_nG723OutPutDataNum +=acmHeader.cbDstLengthUsed;
#endif
//added by ju for test decode g723 data end
#ifdef ACM_FILE_CREATE
if(g_hAcmFile >= 0)
FileWrite(g_hAcmFile, (INT8 *)acmHeader.pbDst, acmHeader.cbDstLengthUsed);
#endif
}
}
if(pwh->dwBufferLength > 0)
{
// memset(pwh->lpData + pwh->dwBufferLength, 0, pVoicePlayParam->dwDstBufferSize - pwh->dwBufferLength);
// pwh->dwBufferLength = pVoicePlayParam->dwDstBufferSize;
request.nu_function = NU_OUTPUT;
pwh->dwFlags = 0;
pwh->dwLoops = 0;
request.nu_supplemental_ptr = (VOID *)pwh;
NU_Request_Driver(pVoicePlayParam->pAudioDrv, &request);
pwh->dwUser = WAVEHDR_IN_USE;
return TRUE;
}
else
return FALSE;
}
return FALSE;
}
VOID __AudioCallbackFunction(WAVEHDR *pwh, DWORD dwUser)
{
MEvent ev;
ev.dwMsgType = VOICE_COMMAND_OUTPUT;
ev.xParam = dwUser;
ev.yParam = 0;
ev.pvInfoPtr = (VOID *)pwh;
// NU_Change_Preemption(NU_PREEMPT);
NU_Send_To_Queue(&g_VoiceQueue, &ev, EVENT_QUEUE_MSG_SIZE, NU_NO_SUSPEND);
}
VOID __AcmCallbackFunction(WAVEHDR *pwh, DWORD dwUser)
{
MEvent ev;
ev.dwMsgType = VOICE_COMMAND_OUTPUT;
ev.xParam = dwUser;
ev.yParam = ACM_STREAMCONVERTF_BLOCKALIGN;
ev.pvInfoPtr = (VOID *)pwh;
// NU_Change_Preemption(NU_PREEMPT);
NU_Send_To_Queue(&g_VoiceQueue, &ev, EVENT_QUEUE_MSG_SIZE, NU_NO_SUSPEND);
}
NU_DRIVER* __VoiceFindAudioDrv(UINT32 dwUser, VOID *pCallBack, WAVEFORMATEX *pWfx)
{
NU_DRIVER_REQUEST request;
AUDIODS_OPEN open;
NU_DRIVER *pAudioDrv;
pAudioDrv = GetIODriverFromName((UINT8 *)"AUDIO");
{
request.nu_function = NU_ASSIGN;
open.dwAudioCommand = AUDIO_PLAY;
open.pwfx = pWfx;
open.dwCallback = pCallBack;
open.dwCallbackInstance = dwUser;
open.fdwOpen = 0;
request.nu_supplemental_ptr = (VOID *)&open;
NU_Request_Driver(pAudioDrv, &request);
if(request.nu_status == MMSYSERR_NOERROR)
return pAudioDrv;
}
return NULL;
}
VoiceHandle __VoiceOpen(MVoicePlayParam *pVoicePlayParam)
{
__VoiceProtect();
//得到句柄
g_VoiceHandle ++;
if(g_VoiceHandle >= (VOICE_HANDLE_MASK | VOICE_HANDLE_MAX))
g_VoiceHandle = (VOICE_HANDLE_MASK | VOICE_HANDLE_MIN);
//拷贝播放参数
memcpy(&g_VoicePlayParam, pVoicePlayParam, sizeof(MVoicePlayParam));
hdrWave1.dwUser = WAVEHDR_NOT_USE;
hdrWave2.dwUser = WAVEHDR_NOT_USE;
hdrWave3.dwUser = WAVEHDR_NOT_USE;
__VoiceUnprotect();
pVoicePlayParam = &g_VoicePlayParam;
pVoicePlayParam->hMediaFile = NULL;
pVoicePlayParam->pAudioDrv = NULL;
pVoicePlayParam->pAcmDrv = NULL;
pVoicePlayParam->pDstBuffer = NULL;
pVoicePlayParam->pSrcBuffer = NULL;
pVoicePlayParam->dwHeadLength = 0;
pVoicePlayParam->dwFrameLength = 1;
if(__VoiceFileOpen(pVoicePlayParam) == FALSE)
{
if(pVoicePlayParam->pCallBackFunc != NULL)
((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)(VOICE_NOTIFY_OPEN_FAIL, 0);
return (VoiceHandle) -1;
}
if(__VoiceFileInfo(pVoicePlayParam) == FALSE)
{
__VoiceFileClose(pVoicePlayParam);
if(pVoicePlayParam->pCallBackFunc != NULL)
((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)(VOICE_NOTIFY_OPEN_FAIL, 0);
return (VoiceHandle) -1;
}
//播放循环次数0表示永不停止
if(pVoicePlayParam->dwPlayCycles == 0)
pVoicePlayParam->dwPlayCycles = VOICE_PLAY_FOREVER;
//检查播放开始位置参数
if(pVoicePlayParam->dwPlayStart >= pVoicePlayParam->dwFileLength)
pVoicePlayParam->dwPlayStart = 0;
//设置播放长度参数
if(pVoicePlayParam->dwPlayLength == 0)
pVoicePlayParam->dwPlayLength = pVoicePlayParam->dwFileLength;
if(pVoicePlayParam->dwPlayStart + pVoicePlayParam->dwPlayLength > pVoicePlayParam->dwFileLength)
pVoicePlayParam->dwPlayLength = pVoicePlayParam->dwFileLength - pVoicePlayParam->dwPlayStart;
//设置播放结束参数
pVoicePlayParam->dwPlayEnd = pVoicePlayParam->dwPlayStart + pVoicePlayParam->dwPlayLength;
pVoicePlayParam->dwPlayOffset = pVoicePlayParam->dwPlayStart;
g_VoiceHandle &= (~VOICE_HANDLE_MASK);
#ifdef ACM_FILE_CREATE
if(!(pVoicePlayParam->playType == VOICE_TYPE_WAV &&
((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->wFormatTag == WAVE_FORMAT_PCM))
{
WAVEFILEHDR waveFileHdr;
FileDelete("/USER/MP3/Acm_mp3_.wav");
g_hAcmFile = FileOpen((UINT8 *)"/USER/MP3/Acm_mp3_.wav", FILEMODE_CREATEWRITE);
if(g_hAcmFile >= 0)
{
strcpy((char *)waveFileHdr.RIFF, "RIFF");
waveFileHdr.dwFileLen = 0x01000000;
strcpy((char *)waveFileHdr.Format, "WAVEfmt ");
waveFileHdr.dwFormatSize = sizeof(WAVEFORMAT);
strcpy((char *)waveFileHdr.data, "data");
waveFileHdr.dwDataLen = waveFileHdr.dwFileLen - 0x24;
waveFileHdr.wfmt.wFormatTag = WAVE_FORMAT_PCM;
waveFileHdr.wfmt.nChannels = ((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->nChannels;
waveFileHdr.wfmt.nSamplesPerSec = ((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->nSamplesPerSec;
waveFileHdr.wfmt.wBitsPerSample = 16;
waveFileHdr.wfmt.nBlockAlign = waveFileHdr.wfmt.nChannels * waveFileHdr.wfmt.wBitsPerSample / 8;
waveFileHdr.wfmt.nAvgBytesPerSec = waveFileHdr.wfmt.nSamplesPerSec * waveFileHdr.wfmt.nBlockAlign;
FileWrite(g_hAcmFile, (INT8 *)&waveFileHdr, sizeof(waveFileHdr));
}
}
else
g_hAcmFile = -1;
#endif
return g_VoiceHandle;
}
BOOL __VoicePlayInit(MVoicePlayParam* pVoicePlayParam)
{
WAVEFORMATEX pcmFormat;
NU_DRIVER_REQUEST request;
// SysWatchChangeFreq(1);
// 寻找合适的音频驱动
pVoicePlayParam->pAudioDrv = __VoiceFindAudioDrv(g_VoiceHandle, (VOID *)__AudioCallbackFunction, (WAVEFORMATEX *)pVoicePlayParam->wfx_buf);
if(pVoicePlayParam->pAudioDrv == NULL)
{
// 寻找合适的解码驱动
if(AcmStreamOpen((HACMSTREAM *)&(pVoicePlayParam->pAcmDrv), NULL,
(WAVEFORMATEX *)pVoicePlayParam->wfx_buf, &pcmFormat, 0) != MMSYSERR_NOERROR)
return FALSE;
// 寻找合适的音频驱动
pVoicePlayParam->pAudioDrv = __VoiceFindAudioDrv(g_VoiceHandle, (VOID *)&__AcmCallbackFunction, &pcmFormat);
if(pVoicePlayParam->pAudioDrv == NULL)
return FALSE;
/* deleted by ju begin
if(pVoicePlayParam->dwLengthPerSec < 16000)
pVoicePlayParam->dwSrcBufferSize = pVoicePlayParam->dwLengthPerSec / 4 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
else
pVoicePlayParam->dwSrcBufferSize = pVoicePlayParam->dwLengthPerSec / 8 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
deleted by ju begin
*/
// added by ju begin
if(pVoicePlayParam->dwLengthPerSec < 16000)
pVoicePlayParam->dwSrcBufferSize = pVoicePlayParam->dwLengthPerSec / 8 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
else
pVoicePlayParam->dwSrcBufferSize = pVoicePlayParam->dwLengthPerSec / 18 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
// added by ju end
// 计算合适的目标缓冲区尺寸
AcmStreamSize((HACMSTREAM )(pVoicePlayParam->pAcmDrv), pVoicePlayParam->dwSrcBufferSize, (DWORD *)(&pVoicePlayParam->dwDstBufferSize), ACM_STREAMSIZEF_SOURCE);
pVoicePlayParam->dwSrcBufferSize = pVoicePlayParam->dwSrcBufferSize / 0x10 * 0x10;
pVoicePlayParam->dwDstBufferSize = pVoicePlayParam->dwDstBufferSize / 0x10 * 0x10;
/* pVoicePlayParam->pDstBuffer = (UINT8 *)__VoiceMemAlloc(pVoicePlayParam, VOICE_BUFFER_NUM * pVoicePlayParam->dwDstBufferSize);
pVoicePlayParam->pSrcBuffer = (UINT8 *)__VoiceMemAlloc(pVoicePlayParam, VOICE_BUFFER_NUM * pVoicePlayParam->dwSrcBufferSize);
if((pVoicePlayParam->pSrcBuffer == NULL) || (pVoicePlayParam->pDstBuffer == NULL))
return FALSE;
hdrWave1.lpData = pVoicePlayParam->pDstBuffer;
hdrWave2.lpData = pVoicePlayParam->pDstBuffer + pVoicePlayParam->dwDstBufferSize;*/
}
else
{
if(pVoicePlayParam->dwLengthPerSec >= 32000)
pVoicePlayParam->dwDstBufferSize = pVoicePlayParam->dwLengthPerSec / 16 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
else if(pVoicePlayParam->dwLengthPerSec >= 16000)
pVoicePlayParam->dwDstBufferSize = pVoicePlayParam->dwLengthPerSec / 8 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
else
pVoicePlayParam->dwDstBufferSize = pVoicePlayParam->dwLengthPerSec / 4 / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
pVoicePlayParam->dwDstBufferSize = pVoicePlayParam->dwDstBufferSize / 0x10 * 0x10;
/* pVoicePlayParam->pDstBuffer = (UINT8 *)__VoiceMemAlloc(pVoicePlayParam, VOICE_BUFFER_NUM * pVoicePlayParam->dwDstBufferSize);
if(pVoicePlayParam->pDstBuffer == NULL)
return FALSE;
hdrWave1.lpData = pVoicePlayParam->pDstBuffer;
hdrWave2.lpData = pVoicePlayParam->pDstBuffer + pVoicePlayParam->dwDstBufferSize;*/
}
#ifdef _WIN32
// zjj deletebegin
memset((UINT8*)&request, 0, sizeof(NU_DRIVER_REQUEST));
request.nu_function = NU_STATUS;
request.nu_timeout = NU_NO_SUSPEND;
request.nu_supplemental_ptr = "buffer_info";
request.nu_supplemental = 0;
NU_Request_Driver(pVoicePlayParam->pAudioDrv, &request);
pVoicePlayParam->pDstBuffer = request.nu_request_info.nu_input.nu_buffer_ptr;
if(pVoicePlayParam->dwDstBufferSize > request.nu_request_info.nu_input.nu_actual_size)
pVoicePlayParam->dwDstBufferSize = request.nu_request_info.nu_input.nu_actual_size;
hdrWave1.lpData = pVoicePlayParam->pDstBuffer;
hdrWave2.lpData = pVoicePlayParam->pDstBuffer + pVoicePlayParam->dwDstBufferSize;
hdrWave3.lpData = pVoicePlayParam->pDstBuffer + 2 * pVoicePlayParam->dwDstBufferSize;
// zjj delete End
#else
// zjj Add begin
if(pVoicePlayParam->pDstBuffer ==NULL)
{
pVoicePlayParam->pDstBuffer = MemAlloc(AUDIO_BUFFER_SIZE*3);
if(pVoicePlayParam->pDstBuffer==NULL) return FALSE;
if(pVoicePlayParam->dwDstBufferSize>AUDIO_BUFFER_SIZE)
pVoicePlayParam->dwDstBufferSize = AUDIO_BUFFER_SIZE;
};//end if
hdrWave1.lpData = pVoicePlayParam->pDstBuffer;
hdrWave2.lpData = pVoicePlayParam->pDstBuffer + AUDIO_BUFFER_SIZE;
hdrWave3.lpData = pVoicePlayParam->pDstBuffer + 2 * AUDIO_BUFFER_SIZE;
// zjj Add End
#endif
return TRUE;
}
BOOL __VoicePlayExit(MVoicePlayParam* pVoicePlayParam)
{
NU_DRIVER_REQUEST request;
if(pVoicePlayParam->pAudioDrv != NULL)
{
request.nu_function = NU_RELEASE;
NU_Request_Driver(pVoicePlayParam->pAudioDrv, &request);
pVoicePlayParam->pAudioDrv = NULL;
}
if(pVoicePlayParam->pAcmDrv != NULL)
{
request.nu_function = NU_RELEASE;
NU_Request_Driver(pVoicePlayParam->pAcmDrv, &request);
pVoicePlayParam->pAcmDrv = NULL;
}
if(pVoicePlayParam->pDstBuffer != NULL)
{
#ifndef WIN32 //wangchengju added the macro
MemFree(pVoicePlayParam->pDstBuffer); // zjj add
#endif
pVoicePlayParam->pDstBuffer = NULL; // zjj delete
}
if(pVoicePlayParam->pSrcBuffer != NULL)
{
// MemFree(pVoicePlayParam->pSrcBuffer);
pVoicePlayParam->pSrcBuffer = NULL;
}
// SysWatchChangeFreq(2);
return TRUE;
}
#ifdef VOICE_TIME_TEST
static NU_TIMER g_VoiceTimer;
static UINT32 dwVoiceTimerCounter;
VOID __VoiceTimerCounter(UNSIGNED dwTimer)
{
dwVoiceTimerCounter ++;
}
HTIMER __VoiceTimerCreate()
{
UINT32 dwTimeLen = 100;
dwVoiceTimerCounter = 0;
memset(&g_VoiceTimer, 0, sizeof(g_VoiceTimer));
#ifdef WIN32
dwTimeLen = ((dwTimeLen + (1000/18/2)) * 18 / 1000);
#else
dwTimeLen = ((dwTimeLen + (1000 /NU_PLUS_Ticks_Per_Second/2)) * NU_PLUS_Ticks_Per_Second / 1000);
#endif
if ( NU_Create_Timer( (NU_TIMER*)&g_VoiceTimer, "VoiceTimer", __VoiceTimerCounter,
0x12345678, dwTimeLen, dwTimeLen, NU_ENABLE_TIMER ) != NU_SUCCESS)
{
return (HTIMER)NULL;
}
GraphClearRect(0x10, 0x10, 0x100, 0x30);
GraphDrawText(0x10, 0x10, 0, 0, (UINT8 *)("DecodeStart "));
return (HTIMER)&g_VoiceTimer;
}
HTIMER __VoiceTimerDestroy()
{
UINT8 szInfo[20];
sprintf((char *)szInfo, "DecodeEnd:%d ", dwVoiceTimerCounter);
NU_Control_Timer((NU_TIMER*)&g_VoiceTimer, NU_DISABLE_TIMER);
NU_Delete_Timer((NU_TIMER*)&g_VoiceTimer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -