📄 maipcmdec.c
字号:
/* <LIC_AMD_STD> * Copyright (C) 2003-2005 Advanced Micro Devices, Inc. All Rights Reserved. * * Unless otherwise designated in writing, this software and any related * documentation are the confidential proprietary information of AMD. * THESE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY * UNLESS OTHERWISE NOTED IN WRITING, EXPRESS OR IMPLIED WARRANTY OF ANY * KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE AND IN NO * EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER. * * AMD does not assume any responsibility for any errors which may appear * in the Materials nor any responsibility to support or update the * Materials. AMD retains the right to modify the Materials at any time, * without notice, and is not obligated to provide such modified * Materials to you. AMD is not obligated to furnish, support, or make * any further information available to you. * </LIC_AMD_STD> *//* <CTL_AMD_STD> * </CTL_AMD_STD> *//* <DOC_AMD_STD> * Filename: maipcmdec.c - PCM Audio decoder interfaces for MAIengine * </DOC_AMD_STD> */#if defined(WIN32) || defined(UNDER_CE) #include <windows.h>#endif#include <stdio.h>#include <stdlib.h>#if !defined(UNDER_CE) #include <fcntl.h> #endif#include "mai_osal.h" /* needed for threads */#include "mai_component.h" #include "mai_compbase.h"#include "audio_change_info.h"#include "wavformats.h"#include "pcmdecode.h"#ifdef TRACE_BUILD#define DPRINTF(_args_) MAIOSDebugPrint _args_ #define APIPRINTF(_args_) MAIOSDebugPrint _args_ #define ERRORPRINTF(_args_) MAIOSDebugPrint _args_ #else#define DPRINTF(_args_) /* MAIOSDebugPrint _args_ */#define APIPRINTF(_args_) /* MAIOSDebugPrint _args_ */#define ERRORPRINTF(_args_) /* MAIOSDebugPrint _args_ */#endif#define DEFAULT_INBUFSIZE 8*1024#define DEFAULT_INBUFCOUNT 8/* Decoder State Definitions: MAI_RUNSTATE_NONE - decoder not initialized MAI_RUNSTATE_INIT - decoder initialized, decodes not started yet MAI_RUNSTATE_PLAYING - decoder initialized, decodes active MAI_RUNSTATE_PAUSED - decoder initialized, decodes paused MAI_RUNSTATE_DESTROYING - MAICompEnd() in progress - destroying decoder*///#define DUMP_TO_FILE //#define DUMP_AUDIO_TO_FILE #define MAX_PCM_OUTBUF_SIZE 0x8000#define PCM_BUF_PAD 2048enum{ UNCOMPRESSED_NONE = 0, UNCOMPRESSED_MPEG_LPCM, UNCOMPRESSED_PCM,};/* Our component's private processor variables are stored here */typedef struct ProcessorInfo_s { unsigned int m_uiProcessLoops; unsigned int m_uiNeedsInit; unsigned int m_uiMaxInBufferSize; unsigned int m_uiStreamPosition; unsigned int m_bNewFormat; unsigned int m_bUncompressedPCM; unsigned int m_uiPrevSRate; unsigned int m_nPrevChannels; unsigned int m_LeftOverInput; unsigned int m_bReversedByteOrder; unsigned int m_bParseFirstWAVframes; audiodecChangeInfo ci; unsigned char *m_pucAudioInBuf; unsigned short *m_pAudioOutBuf; unsigned char m_pucLeftOver[PCM_BUF_PAD];} ProcessorInfo_t;#ifdef DUMP_AUDIO_TO_FILE #define DUMPAUDIO(bb, ss) dump_audio((unsigned char *)bb, ss) void dump_audio(unsigned char *buf, unsigned int size) { static FILE *ofp = NULL; if (ofp == NULL) ofp = fopen("dumpwav.pcm", "wb"); if (ofp != NULL) fwrite(buf, 1, size, ofp); }#else #define DUMPAUDIO(bb, ss) #endifstatic void flip_byte_order(unsigned short *buf, int insize){ int ii; unsigned int temp; unsigned int tempi; insize >>= 1; /* because the insize was based on bytes, not words */ for (ii = 0; ii < insize; ii++) { //temp = tempi = *buf; temp = tempi = buf[ii]; tempi >>= 8; tempi |= (temp << 8); buf[ii] = (short)tempi; //*buf++ = tempi; }}static MAIStatus_e open_pcmdec(ProcessorInfo_t *pPInfo){ /* open the WAV audio decoder */ pPInfo->m_uiProcessLoops = 0; pPInfo->m_uiMaxInBufferSize = 0; pPInfo->m_LeftOverInput = 0; pPInfo->m_bReversedByteOrder = 0; pPInfo->m_uiPrevSRate=0; pPInfo->m_nPrevChannels=0; pPInfo->m_bNewFormat = 1; pPInfo->m_bUncompressedPCM = UNCOMPRESSED_NONE; init_wav_decode(&pPInfo->ci); pPInfo->m_pAudioOutBuf = malloc(MAX_PCM_OUTBUF_SIZE); pPInfo->m_uiNeedsInit = 0; APIPRINTF((M_TEXT("PCMDEC: open_pcmdec() done\n"))); if (pPInfo->m_pAudioOutBuf == NULL) return MAI_STATUS_NOBUFAVAIL; return MAI_STATUS_OK;}MAIStatus_e _startprocessing(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("PCMDEC: _startprocessing() enter\n"))); if (!MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else { APIPRINTF((M_TEXT("PCMDEC: _startprocessing() Init codec\n"))); pPInfo->m_uiNeedsInit = 1; /* Register output setup (needed for Read/WriteBuffer) */ MAICompBase_RegisterOutput(hComp, 0, M_NULL /* pfOutputGetBuffer */, M_NULL /* pfOutputPutBuffer */, hComp, MAX_PCM_OUTBUF_SIZE, 32); } if (eStatus==MAI_STATUS_OK) { MAICompHandleInfo_t *pCompInfo=HCOMP_TO_HANDLEINFO(hComp); /* update codec name in Component info */ strncpy(pCompInfo->Info.pszDesc, wavheader.pcDecoderFullName, 24); /* call default StartProcessing */ MAICompBase_StartProcessing(hComp); } APIPRINTF((M_TEXT("PCMDEC: _startprocessing() exit: status=0x%X\n"), eStatus)); return eStatus;}static void close_pcm(ProcessorInfo_t *pPInfo){ if (pPInfo->m_pAudioOutBuf != NULL) { free(pPInfo->m_pAudioOutBuf); pPInfo->m_pAudioOutBuf = NULL; } if (pPInfo->m_pucAudioInBuf != NULL) { free(pPInfo->m_pucAudioInBuf); pPInfo->m_pucAudioInBuf = NULL; } pPInfo->m_uiNeedsInit = 1; pPInfo->m_uiProcessLoops = 0; close_pcm_decoders();}MAIStatus_e _endprocessing(MAICompHandle_t hComp){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; APIPRINTF((M_TEXT("PCMDEC: _endprocessing() enter\n"))); if (MAICompBase_IsState(hComp, MAI_RUNSTATE_NONE)) eStatus=MAI_STATUS_WRONGSTATE; else close_pcm(pPInfo); MAICompBase_EndProcessing(hComp); APIPRINTF((M_TEXT("PCMDEC: _endprocessing() exit: status=0x%X\n"), eStatus)); return eStatus;}#define NUM_ALLOWED_RATES 10#define DEFAULT_RATE 44100static unsigned int allowed_rates[NUM_ALLOWED_RATES] ={ 8000, 11025, 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000,};static int check_rate(unsigned int check){ int ii; for (ii = 0; ii < NUM_ALLOWED_RATES; ii++) { if (allowed_rates[ii] == check) return check; } return DEFAULT_RATE;}MAIStatus_e _processbuffer(MAICompHandle_t hComp, MAICompBuffer_t *pInBufferInfo){ ProcessorInfo_t *pPInfo=(ProcessorInfo_t *)HCOMP_TO_USERINFO(hComp); MAIStatus_e eStatus = MAI_STATUS_OK; int insize = pInBufferInfo->uiDataSize; unsigned char *inbuf = pInBufferInfo->pBuffer; unsigned char *inbuf_ptr = inbuf; unsigned int uiBufFlags=pInBufferInfo->dwFlags; unsigned int output_sample_count = 0; MAICompBuffer_t BufferInfo; int buf_pad = PCM_BUF_PAD; int last_frame = 0; APIPRINTF((M_TEXT("PCMDEC: _processbuffer(%x) enter\n"), pInBufferInfo->uiDataSize)); #ifdef DUMP_TO_FILE { static FILE *ofp = NULL; if (ofp == NULL) ofp = fopen("c:\\temp\\dumppcm.pcm", "wb"); if (ofp != NULL) fwrite(pInBufferInfo->pBuffer, 1, pInBufferInfo->uiDataSize, ofp); printf("PCM dump to file\n"); } #endif if (pInBufferInfo->uiDataSize) /* we got actual input data */ { /* we are playing again, ensure we are not in IDLE state */ if (MAICompBase_IsState(hComp, MAI_RUNSTATE_IDLE|MAI_RUNSTATE_STARTING)) MAICompBase_ChangeState(hComp, MAI_RUNSTATE_PLAYING); } if ((uiBufFlags&MAICOMPBUF_FLAG_NEWFORMAT)!=0) { /* Start of new format - make sure we're closed after previous format. */ APIPRINTF((M_TEXT("PCMDEC: _processbuffer() NEWFORMAT: close_pcm()\n"))); close_pcm(pPInfo); APIPRINTF((M_TEXT("PCMDEC: _processbuffer() NEWFORMAT: close_pcm() done\n"))); } if (pPInfo->m_uiNeedsInit) { MAIMediaTypeAudio_t *pAudioInfo = (MAIMediaTypeAudio_t *)pInBufferInfo->pBuffer; unsigned char *temp_str = pInBufferInfo->pBuffer; open_pcmdec(pPInfo); DPRINTF((M_TEXT("Check for valid WAV or AIFF header.\n"))); if ((strncmp(temp_str, "RIFF", 4) == 0) || (strncmp(temp_str, "FORM", 4) == 0)) pPInfo->m_bUncompressedPCM = UNCOMPRESSED_NONE; else if (temp_str[0] == 0xa0) // UNCOMPRESSED_MPEG_LPCM { DPRINTF((M_TEXT("PCMDEC: LPCM\n"))); /* examples a0 6 0 ec 7 1 80 ff 42 1 5 ff 4e 1 5 ff a0 6 0 94 d 1 80 2 68 ff 9c 2 74 ff af 2 a0 6 0 a4 6 1 80 0 43 fe f8 0 54 fe ff 0 a0 7 0 4c c 1 80 fe 94 1 57 fe 8b 1 3d fe * MPEG LPCM header * - PES header 0 - private stream ID (8 bits) == 0xA0 A1 == MLP 1 - unknown
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -