📄 codec.c
字号:
//****************************************************************************//// CODEC.C - Generic codec interface layer.//// Copyright (c) 1999,2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"//****************************************************************************//// The following enum must match the ordinal number of the various decoders// in the pfnIoctl table.////****************************************************************************enum{#ifdef SUPPORT_MP3 CODEC_MP3,#endif#ifdef SUPPORT_AAC CODEC_AAC,#endif#ifdef SUPPORT_WMA CODEC_WMA,#endif#ifdef SUPPORT_MSADPCM CODEC_MSADPCM,#endif#ifdef SUPPORT_G721 CODEC_G721,#endif#ifdef SUPPORT_ACELPNET CODEC_ACELPNET,#endif NUMCODECS};//****************************************************************************//// An array of entry points for the codecs supported by the codec interface.////****************************************************************************static unsigned long (* const pfnIoctl[NUMCODECS])(unsigned long ulIoctl, unsigned long ulParam1, unsigned long ulParam2, unsigned long ulParam3, unsigned long ulParam4) ={ // // The MP3 decoder. //#ifdef SUPPORT_MP3 MP3Ioctl,#endif // // The AAC decoder. //#ifdef SUPPORT_AAC AACIoctl,#endif // // The WMA decoder. //#ifdef SUPPORT_WMA WMAIoctl,#endif // // The MS ADPCM encoder/decoder. //#ifdef SUPPORT_MSADPCM MSADPCMIoctl,#endif // // The G.721 encoder/decoder. //#ifdef SUPPORT_G721 G721Ioctl,#endif // // The ACELP.net decoder. //#ifdef SUPPORT_ACELPNET ACELPnetIoctl,#endif};//****************************************************************************//// The following structure contains the persistent state of the generic codec// interface layer.////****************************************************************************static struct{ // // A boolean which is true when there is a codec currently opened. // unsigned char bCodecOpen; // // The codec which is currently opened. // unsigned char ucCodec; // // The flags specified when the current codec was opened. // unsigned char ucFlags;} sCodec;//****************************************************************************//// The following are the GUIDs for the various chunks in an ASF file that we// care about.////****************************************************************************static const unsigned char pucFileHeaderGUID[16] ={ 0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c};static const unsigned char pucStreamFormatGUID[16] ={ 0x91, 0x07, 0xdc, 0xb7, 0xb7, 0xa9, 0xcf, 0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65};//****************************************************************************//// IsRIFFFile determines if the file is a RIFF file, and returns the start of// the data chunk if so.////****************************************************************************static unsigned longIsRIFFFile(tFile *pFile, unsigned char *pucData, unsigned long *pulDataStart){ unsigned long ulOffset; // // Seek to the beginning of the file. // FSSeek(pFile, 0); // // Read the first 512 bytes of data from the file. // FSRead(pFile, pucData, 512); // // Seek back to the beginning of the file. // FSSeek(pFile, 0); // // Is this a RIFF WAVE file? // if((pucData[0] == 'R') && (pucData[1] == 'I') && (pucData[2] == 'F') && (pucData[3] == 'F') && (pucData[8] == 'W') && (pucData[9] == 'A') && (pucData[10] == 'V') && (pucData[11] == 'E')) { // // Find the "data" chunk. // ulOffset = CodecFindRIFFChunk(pucData, 512, 12, "data"); // // If we could not find the "data" chunk, then return an error. // if(ulOffset == -1) { return(0); } // // Return the start of the file data. // if(pulDataStart) { *pulDataStart = ulOffset + 8; } // // Success. // return(1); } // // This file is not a RIFF file. // return(0);}//****************************************************************************//// CodecFindRIFFChunk finds the given chunk in a RIFF file.////****************************************************************************unsigned longCodecFindRIFFChunk(unsigned char *pucData, unsigned long ulLength, unsigned long ulIdx, char *pcName){ // // Loop until we find the specified chunk. // while(1) { // // Is this the correct chunk? // if((pucData[ulIdx] == pcName[0]) && (pucData[ulIdx + 1] == pcName[1]) && (pucData[ulIdx + 2] == pcName[2]) && (pucData[ulIdx + 3] == pcName[3])) { // // This is the correct chunk, so return it's offset. // return(ulIdx); } // // Skip to the next chunk. // ulIdx += 8 + pucData[ulIdx + 4] + (pucData[ulIdx + 5] << 8) + (pucData[ulIdx + 6] << 16) + (pucData[ulIdx + 7] << 24); // // If this chunk starts beyond the piece of the file that we've read, // then quit looking for the specified chunk. // if(ulIdx > ulLength) { return(-1); } }}//****************************************************************************//// CodecIsASFFile determines if the file is an ASF file.////****************************************************************************unsigned longCodecIsASFFile(tFile *pFile, unsigned char *pucData){ // // Seek to the beginning of the file. // FSSeek(pFile, 0); // // Read the first 512 bytes of data from the file. // FSRead(pFile, pucData, 512); // // Seek back to the beginning of the file. // FSSeek(pFile, 0); // // Is this an ASF 1.0 file? // if(memcmp(pucData, pucFileHeaderGUID, 16) == 0) { // // This file is an ASF file. // return(1); } // // This file is not an ASF file. // return(0);}//****************************************************************************//// CodecFindASFChunk finds the given chunk in an ASF file.////****************************************************************************unsigned longCodecFindASFChunk(tFile *pFile, unsigned char *pucData, const unsigned char *pucChunkGUID){ unsigned long ulCount, ulIdx, ulFirst, ulOverlap; // // Seek to the beginning of the file. // FSSeek(pFile, 0); // // Read the first 512 bytes of data from the file. // FSRead(pFile, pucData, 512); // // Get the number of chunks from the file header. // ulCount = ((pucData[27] << 24) | (pucData[26] << 16) | (pucData[25] << 8) | pucData[24]); // // The first chunk starts at offset 30. // ulIdx = 30; // // Loop until we find the specified chunk. // while(1) { // // Is the entire GUID for this chunk in the buffer? // if((ulIdx + 16) >= 512) { // // Get the number of bytes of the GUID that are currently in the // buffer. // ulOverlap = 512 - ulIdx; // // The entire GUID is not in the buffer. Compare the portion of // the GUID that is in the buffer. // ulFirst = memcmp(pucData + ulIdx, pucChunkGUID, ulOverlap); // // Read next portion of the file. // FSRead(pFile, pucData, 512); // // Move the offset to where the beginning of the GUID would be. // ulIdx -= 512; // // Compare the remainder of the GUID. // if(!ulFirst && !memcmp(pucData, pucChunkGUID + ulOverlap, 16 - ulOverlap)) { // // This is the chunk, so return it's offset. // return(ulIdx + 16); } } // // See if the GUID matches the one for which we are searching. // if(!memcmp(pucData + ulIdx, pucChunkGUID, 16)) { // // This is the chunk, so return it's offset. // return(ulIdx + 16); } // // Decrement the count of chunks. // ulCount--; // // If we've looked at all of the chunks, then return a failure. // if(ulCount == 0) { return(-1); } // // Skip to the next chunk. // ulIdx += ((pucData[ulIdx + 19] << 24) | (pucData[ulIdx + 18] << 16) | (pucData[ulIdx + 17] << 8) | pucData[ulIdx + 16]); // // See if this chunk starts in the portion of the file in the buffer. // while(ulIdx >= 512) { // // Decrement the offset by the size of the data in the buffer. // ulIdx -= 512; // // Read the next portion of the file. // FSRead(pFile, pucData, 512); } }}//****************************************************************************//// DetermineCodec parses the file to determine the appropriate codec to use// to decode the file.////****************************************************************************static unsigned longDetermineCodec(tFile *pFile, unsigned char *pucData){ unsigned long ulOffset, ulRet; // // Determine if this is a RIFF file. // if(IsRIFFFile(pFile, pucData, 0) == 1) { // // Find the "fmt " chunk. // ulOffset = CodecFindRIFFChunk(pucData, 512, 12, "fmt "); // // If there is no "fmt " chunk, then return an error. // if(ulOffset == -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -