📄 voicein.c
字号:
/****************************************************************************/
/* */
/* Copyright (C) 2002-2003 SHENZHEN MEIJIN CO.LTD */
/* */
/* FILE NAME : VoiceIn.C */
/* MODULE NAME : Voice模块内部函数(Voice.MOD) */
/* DESCRIPTION : VoiceIn Source File */
/* */
/****************************************************************************/
/* DATE AUTHOR VERSION REMARKS */
/* ========== ======== ======= ============================== */
/* 2004-04-26 黄小明 VER1.00 创建 */
/****************************************************************************/
#define __OS_SOURCE_FILE__
/* 包含所需头文件 */
#include "kernel.h"
//#include "SysWatch.h"
#include "VoiceIn.h"
UINT8 g_VoiceReadEmpty;
//#define ACM_FILE_CREATE 1
//#define VOICE_TIME_TEST
#ifdef ACM_FILE_CREATE
static INT g_hAcmFile = -1;
#endif
//added by ju for test decode g723 data begin
#ifdef VOICE_TIME_TEST
static INT g_nG723OutPutDataNum = 0;
#endif
//added by ju for test decode g723 data end
//Voice任务与队列相关
extern NU_TASK g_VoiceTask;
extern NU_QUEUE g_VoiceQueue;
extern UINT32 g_VoiceQueueBuf[VOICE_MAX_EVENT * EVENT_QUEUE_MSG_SIZE];
extern VOID* g_pVoiceStack;
//Voice状态参数等相关
extern UINT8 g_VoiceStatus; /*状态*/
extern MVoicePlayParam g_VoicePlayParam; /*播放参数*/
extern MVoiceRecordParam g_VoiceRecordParam; /*录音参数*/
extern VoiceHandle g_VoiceHandle; /*句柄*/
extern HTIMER g_hVoiceTimer;
extern OPTION g_VoicePreemptStatus;
extern WAVEHDR hdrWave1, hdrWave2, hdrWave3;
static UINT32 g_dwHdrWavCounter;
VOID __VoiceDataReadCounterClr(VOID);
BOOL __VoiceDataReadCheck(WAVEHDR *pwh);
#define AUDIO_BUFFER_SIZE 0x1200
//UINT8 g_AudioBuffer[2 * AUDIO_BUFFER_SIZE];
/****************************************************************************/
/* FUNCTION: __VoiceTaskProc */
/* DESCRIPTION:Voice任务入口函数 */
/* INPUTS: argc - Voice任务处理的参数个数 */
/* argv - Voice任务处理的参数 */
/* OUTPUTS: NONE */
/* RETURN: NONE */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* HuangXM 2003-06-19 创建 */
/****************************************************************************/
VOID __VoiceTaskProc(UNSIGNED argc, VOID *argv)
{
MEvent ev;
UNSIGNED dwMsgLen;
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
FileBecomeFileUser();
while(1)
{
if( NU_Receive_From_Queue(&g_VoiceQueue, &ev, EVENT_QUEUE_MSG_SIZE, &dwMsgLen, NU_SUSPEND) != NU_SUCCESS )
continue;
SysWatchClear();
switch (ev.dwMsgType)
{
case VOICE_COMMAND_OUTPUT:
if(g_VoiceHandle != (VoiceHandle)ev.xParam)
break;
if((ev.pvInfoPtr != &hdrWave1) &&
(ev.pvInfoPtr != &hdrWave2) &&
(ev.pvInfoPtr != &hdrWave3))
break;
((WAVEHDR *)ev.pvInfoPtr)->dwUser = WAVEHDR_NOT_USE; //
if(g_VoiceStatus == VOICE_STATUS_PLAY)
{
//if check failed, stop current file
if(__VoiceDataReadCheck(ev.pvInfoPtr) == FALSE)
{
__VoiceSendCommand(g_VoiceHandle, VOICE_COMMAND_PLAYEND, 0, 0);
break;
}
if(__VoiceDataRead(ev.pvInfoPtr, ev.yParam) == FALSE)
{
if( (hdrWave1.dwUser == WAVEHDR_NOT_USE) &&
(hdrWave2.dwUser == WAVEHDR_NOT_USE) &&
(hdrWave3.dwUser == WAVEHDR_NOT_USE))
__VoiceSendCommand(g_VoiceHandle, VOICE_COMMAND_PLAYEND, 0, 0);
}
}
break;
case VOICE_COMMAND_INPUT:
RecordWrite((MRecord *)ev.xParam, (WAVEHDR *)ev.pvInfoPtr);
break;
case VOICE_COMMAND_PLAYEND:
if(g_VoiceHandle != (VoiceHandle)ev.pvInfoPtr)
break;
// if(g_VoiceStatus != VOICE_STATUS_PLAY)
// return ;
//检查播放循环是否结束
if((pVoicePlayParam->dwPlayCycles != VOICE_PLAY_FOREVER) && (pVoicePlayParam->dwPlayCycles > 0))
pVoicePlayParam->dwPlayCycles --;
if(pVoicePlayParam->dwPlayCycles == 0)
{
__VoiceStop(VOICE_NOTIFY_FINISH);
if(pVoicePlayParam->playMode & VOICE_MODE_AUTOCLOSE)
{
__VoiceFileClose(pVoicePlayParam);
g_VoiceHandle |= VOICE_HANDLE_MASK;
if(pVoicePlayParam->bListSuspend == TRUE)
VoiceListContinue();
}
break;
// return;
}
else
{
pVoicePlayParam->dwPlayOffset = pVoicePlayParam->dwPlayStart;
__VoicePlayOffsetAdjust(pVoicePlayParam); //
//clear hdrwave read counter
__VoiceDataReadCounterClr();
// 开始解码前两块
if(__VoiceDataRead(&hdrWave1, ACM_STREAMCONVERTF_START|ACM_STREAMCONVERTF_BLOCKALIGN) == TRUE)
{
__VoiceDataRead(&hdrWave2, ACM_STREAMCONVERTF_BLOCKALIGN);
__VoiceDataRead(&hdrWave3, ACM_STREAMCONVERTF_BLOCKALIGN);
}
// __VoiceStop(VOICE_NOTIFY_NONE);
// __VoicePlay(g_VoiceHandle);
}
break;
case VOICE_COMMAND_PLAY:
__VoicePlay((VoiceHandle)ev.pvInfoPtr);
break;
case VOICE_COMMAND_PAUSE:
__VoicePause((VoiceHandle)ev.pvInfoPtr);
break;
case VOICE_COMMAND_RESUME:
__VoiceResume((VoiceHandle)ev.pvInfoPtr);
break;
case VOICE_COMMAND_STOP:
if(g_VoiceHandle != (VoiceHandle)ev.pvInfoPtr)
break;
__VoiceStop((UINT8)ev.xParam);
break;
case VOICE_COMMAND_CLOSE:
__VoiceClose((VoiceHandle)ev.pvInfoPtr);
break;
default:
__VoiceListProcess(ev.dwMsgType);
break ;
}
}
}
BOOL __VoiceTaskReset()
{
if(NU_Terminate_Task(&g_VoiceTask) != NU_SUCCESS)
return FALSE;
//初始化播放任务
if(NU_Reset_Task(&g_VoiceTask,0, NULL) != NU_SUCCESS)
return FALSE;
//初始化播放任务
if(NU_Resume_Task(&g_VoiceTask) != NU_SUCCESS)
return FALSE;
//初始化播放消息队列
if(NU_Reset_Queue(&g_VoiceQueue) != NU_SUCCESS)
return FALSE;
return TRUE;
}
BOOL __VoiceCheck(MVoicePlayParam *pVoicePlayParam)
{
/* if(pVoicePlayParam->pAudioDrv == NULL || pVoicePlayParam->pDstBuffer == NULL)
{
while(1);
return FALSE;
}
else*/
return TRUE;
}
BOOL __VoiceSendCommand(VoiceHandle voiceHandle, UINT32 dwMsgType, UINT16 xParam, UINT16 yParam)
{
MEvent ev;
ev.dwMsgType = dwMsgType;
ev.xParam = xParam;
ev.yParam = yParam;
ev.pvInfoPtr = (VOID *)voiceHandle;
NU_Change_Preemption(NU_PREEMPT);
NU_Send_To_Queue(&g_VoiceQueue, &ev, EVENT_QUEUE_MSG_SIZE, NU_NO_SUSPEND);
return TRUE;
}
VOID __VoiceTimerCallBack()
{
VOICECALLBACKPROC pCallBack = NULL;
MVoicePlayParam* pVoicePlayParam = &g_VoicePlayParam;
MVoiceRecordParam* pVoiceRecordParam = &g_VoiceRecordParam;
//当前在放音
if((g_VoiceStatus == VOICE_STATUS_PLAY)
|| (g_VoiceStatus == VOICE_STATUS_PLAYPAUSE))
{
//回调通知放音被打断
if(pVoicePlayParam->pCallBackFunc != NULL)
pCallBack = (VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc;
else
return;
}
//当前在录音
else if((g_VoiceStatus == VOICE_STATUS_RECORD)
|| (g_VoiceStatus == VOICE_STATUS_RECORDPAUSE))
{
//回调通知录音被打断
if(pVoiceRecordParam->pCallBackFunc != NULL)
pCallBack = (VOICECALLBACKPROC)pVoiceRecordParam->pCallBackFunc;
else
return;
}
if(pCallBack != NULL)
pCallBack(VOICE_NOTIFY_REFRESH, 0);
return ;
}
BOOL __VoiceFileOpen(MVoicePlayParam* pVoicePlayParam)
{
UINT32 dwOpenMode;
if(pVoicePlayParam->playMode & VOICE_MODE_BACKGROUND)
dwOpenMode = MMIO_DENYWRITE | MMIO_ALLOCBUF;
else
dwOpenMode = MMIO_READ | MMIO_ALLOCBUF;
if(pVoicePlayParam->playMode & VOICE_MODE_FILENAME)
{
memcpy(pVoicePlayParam->szFileName, pVoicePlayParam->pDataSource, FILE_MAX_NAMELEN + 1);
// if(pVoicePlayParam->playType == VOICE_TYPE_DEFAULT)
{
if(stricmp((INT8 *)pVoicePlayParam->szFileName + strlen((INT8 *)pVoicePlayParam->szFileName) - 4, ".mp3") == 0)
pVoicePlayParam->playType = VOICE_TYPE_MP3;
else if(stricmp((INT8 *)pVoicePlayParam->szFileName + strlen((INT8 *)pVoicePlayParam->szFileName) - 4, ".wav") == 0)
pVoicePlayParam->playType = VOICE_TYPE_WAV;
else if(stricmp((INT8 *)pVoicePlayParam->szFileName + strlen((INT8 *)pVoicePlayParam->szFileName) - 4, ".wma") == 0)
pVoicePlayParam->playType = VOICE_TYPE_WMA;
}
//
// pVoicePlayParam->hMediaFile =
// MediaFileOpen((INT8 *)pVoicePlayParam->szFileName, &pVoicePlayParam->mmioInfo, dwOpenMode);
}
//added by Liang Ruhui on 2007-06-22
else if(pVoicePlayParam->playMode & VOICE_MODE_CALLBACK){
pVoicePlayParam->szFileName[0] = 0;
pVoicePlayParam->szFileName[1] = 1;
pVoicePlayParam->mmioInfo.pchBuffer = pVoicePlayParam->pDataSource;
pVoicePlayParam->mmioInfo.cchBuffer = pVoicePlayParam->dwPlayLength;
}
else
{
pVoicePlayParam->szFileName[0] = 0;
pVoicePlayParam->szFileName[1] = 2;
pVoicePlayParam->mmioInfo.pchBuffer = pVoicePlayParam->pDataSource;
pVoicePlayParam->mmioInfo.cchBuffer = pVoicePlayParam->dwPlayStart
+ pVoicePlayParam->dwPlayLength;
}
pVoicePlayParam->hMediaFile =
MediaFileOpen((INT8 *)pVoicePlayParam->szFileName, &pVoicePlayParam->mmioInfo, dwOpenMode);
if(pVoicePlayParam->hMediaFile == NULL)
return FALSE;
return TRUE;
}
BOOL __VoiceFileInfo(MVoicePlayParam *pVoicePlayParam)
{
if(MediaFileGetFormat(pVoicePlayParam->hMediaFile, pVoicePlayParam->playType,
(WAVEFORMATEX *)pVoicePlayParam->wfx_buf, &(pVoicePlayParam->dwFileLength),
&(pVoicePlayParam->dwTimeLength)) != MMSYSERR_NOERROR)
return FALSE;
pVoicePlayParam->dwLengthPerSec = ((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->nAvgBytesPerSec;
pVoicePlayParam->dwFrameLength = ((WAVEFORMATEX *)pVoicePlayParam->wfx_buf)->nBlockAlign;
pVoicePlayParam->dwHeadLength = MediaFileSeek(pVoicePlayParam->hMediaFile, 0, 1);
// if(pVoicePlayParam->dwFileLength <= pVoicePlayParam->dwHeadLength)
// return FALSE;
// pVoicePlayParam->dwFileLength -= pVoicePlayParam->dwHeadLength;
//参数非法
if(pVoicePlayParam->dwLengthPerSec == 0)
return FALSE;
// if(pVoicePlayParam->playType != VOICE_TYPE_WMA)
// pVoicePlayParam->dwTimeLength = pVoicePlayParam->dwFileLength / pVoicePlayParam->dwLengthPerSec;
// if(pVoicePlayParam->dwTimeLength < 1)
// pVoicePlayParam->dwTimeLength = 1;
return TRUE;
}
BOOL __VoiceFileClose(MVoicePlayParam* pVoicePlayParam)
{
//如果文件名模式要关闭文件
if(pVoicePlayParam->hMediaFile != NULL)
{
MediaFileClose(pVoicePlayParam->hMediaFile, 0);
pVoicePlayParam->hMediaFile = NULL;
}
#ifdef ACM_FILE_CREATE
if(g_hAcmFile >= 0)
{
UINT32 dwFileLen;
//Rewrite wave file header(filelen & datalen)
dwFileLen = FileLength(g_hAcmFile) - 8;
FileSeek(g_hAcmFile, 0x4, FILESEEK_BEGIN);
FileWrite(g_hAcmFile, &dwFileLen, 4);
dwFileLen -= 0x24;
FileSeek(g_hAcmFile, 0x28, FILESEEK_BEGIN);
FileWrite(g_hAcmFile, &dwFileLen, 4);
FileClose(g_hAcmFile);
g_hAcmFile = -1;
FlashUpdate();
#ifdef _WIN32
#include "stdio.h"
{
FILE *fp;
UINT32 dwFileLen;
UINT8 *pBuf;
g_hAcmFile = FileOpen("/USER/MP3/Acm.wav", FILEMODE_READONLY);
fp = fopen(".\\Flash\\USER\\MP3\\Acm_Pc.wav", "wb");
if(g_hAcmFile >= 0 && fp)
{
dwFileLen = FileLength(g_hAcmFile);
pBuf = malloc(dwFileLen);
if(pBuf)
{
FileRead(g_hAcmFile, pBuf, dwFileLen);
fwrite(pBuf, dwFileLen, 1, fp);
free(pBuf);
}
}
FileClose(g_hAcmFile);
fclose(fp);
g_hAcmFile = -1;
}
#endif
}
#endif
return TRUE;
}
UINT32 __VoiceFileDataRead(UINT32 dwUser, UINT8* pBuf, UINT32 dwReadOffset, UINT32 dwReadLen)
{
MVoicePlayParam* pVoicePlayParam;
UINT32 dwRetLen, bakPlayLen;
BOOL bFinish = FALSE;
pVoicePlayParam = (MVoicePlayParam* )dwUser;
pVoicePlayParam->dwPlayOffset = dwReadOffset / pVoicePlayParam->dwFrameLength * pVoicePlayParam->dwFrameLength;
MediaFileSeek(pVoicePlayParam->hMediaFile, pVoicePlayParam->dwPlayOffset + pVoicePlayParam->dwHeadLength, 0);
if (dwReadLen >= pVoicePlayParam->dwPlayEnd - pVoicePlayParam->dwPlayOffset)
{
dwReadLen = pVoicePlayParam->dwPlayEnd - pVoicePlayParam->dwPlayOffset;
bFinish = TRUE;
}
if (dwReadLen == 0)
return dwReadLen;
dwRetLen = MediaFileRead(pVoicePlayParam->hMediaFile, pBuf, dwReadLen);
if (dwRetLen > dwReadLen)
dwRetLen = 0;
pVoicePlayParam->dwPlayOffset += dwRetLen;
if (bFinish && pVoicePlayParam->pCallBackFunc) {
bakPlayLen = pVoicePlayParam->dwPlayLength;
pVoicePlayParam->dwPlayLength = 0;
((VOICECALLBACKPROC)pVoicePlayParam->pCallBackFunc)
(VOICE_NOTIFY_BUFFER_USEUP, (UINT32)pVoicePlayParam);
if (pVoicePlayParam->dwPlayLength != 0) {
pVoicePlayParam->dwPlayOffset = pVoicePlayParam->dwPlayStart;
pVoicePlayParam->dwPlayEnd = pVoicePlayParam->dwPlayStart
+ pVoicePlayParam->dwPlayLength;
}
else
pVoicePlayParam->dwPlayLength = bakPlayLen;
}
// pVoicePlayParam->dwPlayOffset = MediaFileSeek(pVoicePlayParam->hMediaFile, 0, 1);
// pVoicePlayParam->dwPlayOffset -= pVoicePlayParam->dwHeadLength;
return dwRetLen;
}
#ifdef VOICE_TIME_TEST
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -