#include #include #include #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 /////////////////////////////////////////////////////////////////////////////// #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