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

📄 voicein.c

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