416 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			416 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include <kwrap/error_no.h>
 | |
| #include "FileSysTsk.h"
 | |
| //#include "PStore.h"
 | |
| //#include "SysCommon.h"
 | |
| #include "GxSound.h"
 | |
| #include "kdrv_audioio/audlib_aac.h"
 | |
| #include "WavPlay.h"
 | |
| #include "sys_mempool.h"
 | |
| #include "UIWnd/UIFlow.h"
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| #define __MODULE__				WavPlay
 | |
| #define __DBGLVL__				5////2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER
 | |
| #define __DBGFLT__				"*" //*=All, [mark]=CustomClass
 | |
| #include <kwrap/debug.h>
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #if (WAV_PLAY_FUNC == ENABLE)
 | |
| 
 | |
| #define PS_WAV_MERGE_DATA		"WAVMERGE"	// cannot over 12 characters
 | |
| #define WAV_DATA_MAX			150			// max 150 wav files
 | |
| #define AAC_BUF_SIZE			(80*1024)	// 80KB for AAC data
 | |
| #define WAV_IN_USER_PARTITION	ENABLE//DISABLE
 | |
| 
 | |
| #if (USER_PACK_UPDATE == DISABLE)
 | |
| #undef WAV_IN_USER_PARTITION
 | |
| #define WAV_IN_USER_PARTITION	DISABLE
 | |
| #endif
 | |
| 
 | |
| #if (WAV_IN_USER_PARTITION == DISABLE)
 | |
| #include "WavData.c"
 | |
| #endif
 | |
| 
 | |
| static UINT32		g_WavHeaderAddr = 0;
 | |
| static BOOL			g_WavPlayInit = FALSE;
 | |
| static SOUND_DATA	g_SoundData; // it needs to use global variable for GxSound
 | |
| 
 | |
| ER WavPlay_DecodeAAC(UINT32 inAddr, UINT32 outAddr, UINT32 inLen, UINT32 *pOutLen, AUDLIB_AAC_CFG *pAACDConfig)
 | |
| {
 | |
| 	UINT32				uiBsLen;			// AAC bs length
 | |
| 	UINT32				uiRemainBsLen;		// remaining AAC bs length
 | |
| 	UINT32				uiBsAddr;			// current AAC bs address
 | |
| 	UINT32				uiRawAddr;			// current raw output address
 | |
| 	UINT32				uiAACFrameLen;		// AAC frame length
 | |
| 	UINT32				uiAACFrameNum;		// AAC frame number
 | |
| 	INT32				ErrorCode = E_OK;	// error code
 | |
| 	AUDLIB_AAC_BUFINFO	AACDBuf;			// AAC decoder buffer info
 | |
| 	AUDLIB_AACD_RTNINFO	AACDRtn;			// AAC decoder return info
 | |
| 
 | |
| 	if ((ErrorCode = audlib_aac_decode_init(pAACDConfig)) != E_OK)
 | |
| 	{
 | |
| 		DBG_ERR("AAC decoder init error %d!\r\n", ErrorCode);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	// init buffer address
 | |
| 	uiBsLen = inLen;
 | |
| 	uiBsAddr = inAddr;
 | |
| 	uiRawAddr = outAddr;
 | |
| 	uiRemainBsLen = uiBsLen;
 | |
| 	uiAACFrameNum = 0;
 | |
| 
 | |
| 	while (uiBsAddr < (inAddr + uiBsLen))
 | |
| 	{
 | |
| 		AACDBuf.bitstram_buffer_in	= uiBsAddr;
 | |
| 		AACDBuf.bitstram_buffer_out	= uiRawAddr;
 | |
| 		AACDBuf.bitstram_buffer_length	= uiRemainBsLen;
 | |
| 
 | |
| 		if ((ErrorCode = audlib_aac_decode_one_frame(&AACDBuf, &AACDRtn)) != E_OK)
 | |
| 		{
 | |
| 			DBG_ERR("AAC decode error %d!\r\n", ErrorCode);
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 
 | |
| 		uiAACFrameLen = AACDRtn.one_frame_consume_bytes;
 | |
| 		uiBsAddr += uiAACFrameLen;
 | |
| 		uiRawAddr += AACDRtn.output_size * AACDRtn.channel_number * 2; // 2 bytes per sample
 | |
| 		uiRemainBsLen -= uiAACFrameLen;
 | |
| 
 | |
| 		uiAACFrameNum++;
 | |
| 	}
 | |
| 
 | |
| 	*pOutLen = uiRawAddr - outAddr;
 | |
| 
 | |
|     return E_OK;
 | |
| }
 | |
| 
 | |
| ER WavPlay_WriteWavData(void)
 | |
| {
 | |
| 	#define WAV_READ_BUF_SIZE   0x400000 // 4MB
 | |
| 
 | |
| 	FST_FILE	pFile;
 | |
| 	char		*pFileName = "A:\\WavMerge.bin";
 | |
| 	UINT32		uiFileSize;
 | |
| 	UINT32		pBuf;
 | |
| 
 | |
| 	pBuf = SxCmd_GetTempMem(WAV_READ_BUF_SIZE);
 | |
| 
 | |
| 	if (pBuf == 0)
 | |
| 	{
 | |
| 		DBG_ERR("No enough buffer for sound data reading!\r\n");
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	// open wav merge file (WavMerge.bin)
 | |
| 	pFile = FileSys_OpenFile(pFileName, FST_OPEN_READ);
 | |
| 	uiFileSize = WAV_READ_BUF_SIZE; // max reading size
 | |
| 	if (pFile)
 | |
| 	{
 | |
| 		FileSys_ReadFile(pFile, (UINT8 *)pBuf, &uiFileSize, 0, NULL);
 | |
| 		FileSys_CloseFile(pFile);
 | |
| 		DBG_MSG("File %s, size %d\r\n", pFileName, uiFileSize);
 | |
| 
 | |
| 		if (uiFileSize == WAV_READ_BUF_SIZE)
 | |
| 		{
 | |
| 			DBG_ERR("Read buffer is not enough!\r\n");
 | |
| 			SxCmd_RelTempMem(pBuf);
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		DBG_ERR("Open %s for reading failed!\r\n", pFileName);
 | |
| 		SxCmd_RelTempMem(pBuf);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	// write merged wav data to user partition
 | |
| 	if (UserPartition_Write((INT8 *)pBuf, 0, uiFileSize, USR_PARTI_WAV_DATA) != E_OK)
 | |
| 	{
 | |
| 		DBG_ERR("write wav data to USR_PARTI_WAV_DATA failed!\r\n");
 | |
| 		SxCmd_RelTempMem(pBuf);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	SxCmd_RelTempMem(pBuf);
 | |
| 
 | |
| 	return E_OK;
 | |
| }
 | |
| 
 | |
| ER WavPlay_Init(void)
 | |
| {
 | |
| 	UINT32	uiSize;
 | |
| 	UINT32	uiPoolSize;
 | |
| 
 | |
| 	if (g_WavPlayInit == FALSE)
 | |
| 	{
 | |
| 		g_WavHeaderAddr = mempool_wavplay_header;
 | |
| 		uiPoolSize = POOL_SIZE_WAV_PLAY_HEADER;
 | |
| 
 | |
| 	    uiSize = sizeof(WAV_MERGE_DATA) * WAV_DATA_MAX;
 | |
| 	    DBG_IND("wav header size = %d\r\n", uiSize);
 | |
| 
 | |
| 		if (uiSize > uiPoolSize)
 | |
| 		{
 | |
| 			DBG_ERR("read wav header error, buffer not enough!\r\n");
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 
 | |
| 		if (UserPartition_Read((INT8 *)g_WavHeaderAddr, 0, uiSize, USR_PARTI_WAV_DATA) != E_OK)
 | |
| 		{
 | |
| 			DBG_ERR("read wav header from USR_PARTI_WAV_DATA failed!\r\n");
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 
 | |
| 		g_WavPlayInit = TRUE;
 | |
| 	}
 | |
| 
 | |
| 	return E_OK;
 | |
| }
 | |
| 
 | |
| ER WavPlay_PlayData(char *pName, UINT32 isWav)
 | |
| {
 | |
| 	UINT32			i;
 | |
| 	UINT32			pBuf;
 | |
| 	WAV_MERGE_DATA	*pWavData;
 | |
| 
 | |
| 	if (GxSound_IsPlaying())
 | |
| 	{
 | |
| 		DBG_ERR("sound is playing, cannot play now!\r\n");
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| #if WAV_IN_USER_PARTITION
 | |
| 
 | |
| 	if (WavPlay_Init() != E_OK)
 | |
| 	{
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| #else
 | |
| 
 | |
| 	if (isWav == FALSE) // AAC data
 | |
| 	{
 | |
| 		g_WavHeaderAddr = (UINT32)uiAACData;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		g_WavHeaderAddr = (UINT32)uiWavData;
 | |
| 	}
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 	// compare wav file name
 | |
| 	i = 0;
 | |
| 	while (i < WAV_DATA_MAX)
 | |
| 	{
 | |
| 		pWavData = (WAV_MERGE_DATA *)(g_WavHeaderAddr + sizeof(WAV_MERGE_DATA) * i);
 | |
| 		if (strcmp(pWavData->FileName, pName) == 0)
 | |
| 		{
 | |
| 			DBG_IND("Find name %s, addr 0x%x, size 0x%x\r\n", pWavData->FileName, pWavData->uiAddr, pWavData->uiSize);
 | |
| 			break;
 | |
| 		}
 | |
| 		i++;
 | |
| 	}
 | |
| 
 | |
| 	if (i == WAV_DATA_MAX)
 | |
| 	{
 | |
| 		DBG_ERR("No %s found!\r\n", pName);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| #if WAV_IN_USER_PARTITION
 | |
| 
 | |
| 	UINT32	uiPoolSize;
 | |
| 
 | |
| 	pBuf = mempool_wavplay_data;
 | |
| 	uiPoolSize = POOL_SIZE_WAV_PLAY_DATA;
 | |
| 
 | |
| 	if (pWavData->uiSize > uiPoolSize)
 | |
| 	{
 | |
| 		DBG_ERR("read wav data error, buffer not enough!\r\n");
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	if (isWav == FALSE) // AAC data
 | |
| 	{
 | |
| 		pBuf = pBuf + uiPoolSize - AAC_BUF_SIZE;
 | |
| 	}
 | |
| 
 | |
| 	if (UserPartition_Read((INT8 *)pBuf, pWavData->uiAddr, pWavData->uiSize, USR_PARTI_WAV_DATA) != E_OK)
 | |
| 	{
 | |
| 		DBG_ERR("read wav data from USR_PARTI_WAV_DATA failed!\r\n");
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| #else
 | |
| 
 | |
| 	pBuf = g_WavHeaderAddr + pWavData->uiAddr;
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 	if (isWav == FALSE) // AAC data
 | |
| 	{
 | |
| 		ER				err;
 | |
| 		UINT32			PCMBuf;
 | |
| 		UINT32			PCMLen;
 | |
| 		AUDLIB_AAC_CFG	AACDConfig; // AAC decoder config
 | |
| 
 | |
| 		AACDConfig.sample_rate = 16000;
 | |
| 		AACDConfig.channel_number = 1;
 | |
| 		AACDConfig.header_enable = TRUE;
 | |
| 
 | |
| 		PCMBuf = mempool_wavplay_data;
 | |
| 		err = WavPlay_DecodeAAC(pBuf, PCMBuf, pWavData->uiSize, &PCMLen, &AACDConfig);
 | |
| 
 | |
| 		if (err == E_OK)
 | |
| 		{
 | |
| 			// play wav data
 | |
| 			g_SoundData.puiData = (const UINT8 *)PCMBuf;
 | |
| 			g_SoundData.uiSize = PCMLen;
 | |
| 			g_SoundData.sampleRate = 16000;
 | |
| 			g_SoundData.isMono = TRUE;
 | |
| 			g_SoundData.soundId = 0xFFFFFFFF;
 | |
| 			GxSound_SetPlayCount(1);
 | |
| 			err = GxSound_ActOnSndNotInTbl(SOUND_PLAY_START, &g_SoundData, TRUE);
 | |
| 		}
 | |
| 
 | |
| 		return err;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		// play wav data
 | |
| 		g_SoundData.puiData = (const UINT8 *)pBuf;
 | |
| 		g_SoundData.isMono = TRUE;
 | |
| 		GxSound_SetPlayCount(1);
 | |
| 		GxSound_ActOnSndNotInTbl(SOUND_PLAY_START, &g_SoundData, FALSE);
 | |
| 	}
 | |
| 
 | |
|     return E_OK;
 | |
| }
 | |
| 
 | |
| ER WavPlay_PlayWavData(char *pName)
 | |
| {
 | |
| 	return WavPlay_PlayData(pName, TRUE);
 | |
| }
 | |
| 
 | |
| ER WavPlay_PlayAACData(char *pName)
 | |
| {
 | |
| 	return WavPlay_PlayData(pName, FALSE);
 | |
| }
 | |
| 
 | |
| ER WavPlay_PlayWavDataFromFile(char *pFileName)
 | |
| {
 | |
| 	FST_FILE	pFile;
 | |
| 	UINT32		uiFileSize;
 | |
| 	UINT32		pBuf;
 | |
| 	UINT32		uiPoolSize;
 | |
| 
 | |
| 	pBuf = mempool_wavplay_data;
 | |
| 	uiPoolSize = POOL_SIZE_WAV_PLAY_DATA;
 | |
| 
 | |
| 	// open wav file
 | |
| 	pFile = FileSys_OpenFile(pFileName, FST_OPEN_READ);
 | |
| 	uiFileSize = uiPoolSize; // max reading size
 | |
| 	if (pFile)
 | |
| 	{
 | |
| 		FileSys_ReadFile(pFile, (UINT8 *)pBuf, &uiFileSize, 0, NULL);
 | |
| 		FileSys_CloseFile(pFile);
 | |
| 		DBG_DUMP("File %s, size %d\r\n", pFileName, uiFileSize);
 | |
| 
 | |
| 		if (uiFileSize == uiPoolSize)
 | |
| 		{
 | |
| 			DBG_ERR("Read buffer is not enough!\r\n");
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		DBG_ERR("Open %s for reading failed!\r\n", pFileName);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	if (GxSound_IsPlaying())
 | |
| 	{
 | |
| 		DBG_ERR("sound is playing, cannot play now!\r\n");
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	// play wav data
 | |
| 	g_SoundData.puiData = (const UINT8 *)pBuf;
 | |
| 	g_SoundData.isMono = TRUE;
 | |
| 	GxSound_SetPlayCount(1);
 | |
| 	GxSound_ActOnSndNotInTbl(SOUND_PLAY_START, &g_SoundData, FALSE);
 | |
| 
 | |
|     return E_OK;
 | |
| }
 | |
| 
 | |
| ER WavPlay_PlayAACDataFromFile(char *pFileName)
 | |
| {
 | |
| 	ER				err;
 | |
| 	FST_FILE		pFile;
 | |
| 	UINT32			uiFileSize;
 | |
| 	UINT32			uiPoolSize;
 | |
| 	UINT32			PCMBuf, AACBuf;
 | |
| 	UINT32			PCMLen;
 | |
| 	AUDLIB_AAC_CFG	AACDConfig; // AAC decoder config
 | |
| 
 | |
| 	PCMBuf = mempool_wavplay_data;
 | |
| 	AACBuf = PCMBuf + POOL_SIZE_WAV_PLAY_DATA - AAC_BUF_SIZE;
 | |
| 	uiPoolSize = AAC_BUF_SIZE;
 | |
| 
 | |
| 	// open wav file
 | |
| 	pFile = FileSys_OpenFile(pFileName, FST_OPEN_READ);
 | |
| 	uiFileSize = uiPoolSize; // max reading size
 | |
| 	if (pFile)
 | |
| 	{
 | |
| 		FileSys_ReadFile(pFile, (UINT8 *)AACBuf, &uiFileSize, 0, NULL);
 | |
| 		FileSys_CloseFile(pFile);
 | |
| 		DBG_DUMP("File %s, size %d\r\n", pFileName, uiFileSize);
 | |
| 
 | |
| 		if (uiFileSize == uiPoolSize)
 | |
| 		{
 | |
| 			DBG_ERR("Read buffer is not enough!\r\n");
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		DBG_ERR("Open %s for reading failed!\r\n", pFileName);
 | |
| 		return E_SYS;
 | |
| 	}
 | |
| 
 | |
| 	// decode AAC
 | |
| 	AACDConfig.sample_rate = 16000;
 | |
| 	AACDConfig.channel_number = 1;
 | |
| 	AACDConfig.header_enable = TRUE;
 | |
| 
 | |
| 	err = WavPlay_DecodeAAC(AACBuf, PCMBuf, uiFileSize, &PCMLen, &AACDConfig);
 | |
| 
 | |
| 	if (err == E_OK)
 | |
| 	{
 | |
| 		if (GxSound_IsPlaying())
 | |
| 		{
 | |
| 			DBG_ERR("sound is playing, cannot play now!\r\n");
 | |
| 			return E_SYS;
 | |
| 		}
 | |
| 
 | |
| 		// play wav data
 | |
| 		g_SoundData.puiData = (const UINT8 *)PCMBuf;
 | |
| 		g_SoundData.uiSize = PCMLen;
 | |
| 		g_SoundData.sampleRate = 16000;
 | |
| 		g_SoundData.isMono = TRUE;
 | |
| 		g_SoundData.soundId = 0xFFFFFFFF;
 | |
| 		GxSound_SetPlayCount(1);
 | |
| 		err = GxSound_ActOnSndNotInTbl(SOUND_PLAY_START, &g_SoundData, TRUE);
 | |
| 	}
 | |
| 
 | |
|     return err;
 | |
| }
 | |
| 
 | |
| #endif // WAV_PLAY_FUNC
 | |
| 
 | 
