⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 voicein.c

📁 好记星的控件,包括button,list,对文件操作
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************/
/*                                                                          */
/*              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 + -