📄 aac.c
字号:
//****************************************************************************//// AAC.C - Codec interface driver for the AAC decoder.//// Copyright (c) 2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"#ifdef SUPPORT_AAC#include "aac/aac.h"#include "buffer/buffer.h"#include "src/src.h"//****************************************************************************//// This code has the following limitations://// 1) Bitrate and track length are supported only for constant bit rate ADIF// format streams. Variable bit rate ADIF streams encode the maximum peak// bitrate for an individual frame; the average bitrate is needed to// compute the track length. Other formats do not encode the bitrate in// any way and therefore the track length can not be computed either.// Computing the bitrate would require decoding (effectively) the entire// file. The bitrate and track length are returned as 0 for streams for// which we can not determine the bitrate and track length.//// 2) Raw AAC streams are not supported, only ADIF and ADTS. The AAC decoder// will decode raw AAC streams but we have no way of determining that a// random bitstream is a valid raw AAC stream (outside of decoding a frame// or two of audio, which takes too much time).//// 3) The only position to which seek is supported is the beginning of the// file. It is only possible to seek in an ADTS bitstream since it is the// only format that has frame headers (i.e. seek points) throughout the// data stream. But since the bitrate and track length of an ADTS// bitstream are not encoded in the stream and are not easily computed, it// is not possible to know how to seek to 1500 milliseconds (for example)// into the stream.//// All of these problems can be solved by encapsulating the AAC bitstream in// a meta-file structure which provides additional information about the// stream. It will never be possible to seek within an ADIF stream, however.// It is preferable to have a standard meta-file structure used by everybody// instead of a bunch of home-brew formats, each used only by a particular// content distribution channel.////****************************************************************************//****************************************************************************//// The name of this codec.////****************************************************************************static const unsigned short pusCodecName[] ={ 'A', 'A', 'C', ' ', '2', '.', '0', '.', '0', '.', '0', ' ', 'C', 'h', 'a', 'n', 'n', 'e', 'l', ' ', 'L', 'o', 'w', ' ', 'C', 'o', 'm', 'p', 'l', 'e', 'x', 'i', 't', 'y', ' ', 'M', 'P', 'E', 'G', '-', '2', ' ', 'A', 'A', 'C', ' ', 'D', 'e', 'c', 'o', 'd', 'e', 'r', '\0'};//****************************************************************************//// The size of the output buffer that will be used.////****************************************************************************#define AAC_MAX_PCM_LENGTH 1024//****************************************************************************//// A structure which defines the persistent state of the AAC decoder.////****************************************************************************typedef struct{ // // A pointer to the buffer containing the persistent internal state of the // AAC decoder library. // tAAC_Decoder *pAACInstance; // // The file from which we read data. // tFile *pFile; // // A buffer to contain the encoded AAC audio. // char pcEncodedData[2048]; // // Buffers to contain the decoded AAC audio. // short psLeft[AAC_MAX_PCM_LENGTH + AAC_MAX_PCM_LENGTH + NUMTAPS - 1]; short psRight[AAC_MAX_PCM_LENGTH + AAC_MAX_PCM_LENGTH + NUMTAPS - 1]; // // The buffer to which we write decoded AAC data. // BufferState *pOutput; // // The AAC bitstream pointer. // tAAC_Bitstream sBS; // // The encoded fixed frame header of the AAC stream with which we are // dealing. If we are decoding an ADIF stream, then this is zero. // unsigned long ulHeader; // // The decoded AAC header information. // tAAC_Header sHdr; // // The sample rate of the decoded PCM stream. // unsigned short usSampleRate; // // The number of channels in the file. // unsigned char ucChannels; // // An unused byte to pad the next member to a word boundary. // unsigned char ucUnused; // // The length of the file. // unsigned long ulTimeLength; // // The bit rate of the AAC file. // unsigned long ulBitRate; // // The number of samples which have been decoded. // unsigned long ulTimePos;} tAAC;//****************************************************************************//// The following is a mapping from the sample rate descriptor in the// tAAC_Header structure to the integer number of samples per second.////****************************************************************************static const unsigned long ulSRMap[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 };//****************************************************************************//// The codec plug-in entry point for the AAC decoder.////****************************************************************************unsigned longAACIoctl(unsigned long ulIoctl, unsigned long ulParam1, unsigned long ulParam2, unsigned long ulParam3, unsigned long ulParam4){ // // Determine what to do based on the specified IOCTL. // switch(ulIoctl) { // // Return the name for this codec. // case IOCTL_CODEC_GETNAME: { const unsigned short **ppusName; // // The secod parameter is a pointer for the name. // ppusName = (const unsigned short **)ulParam2; // // Return the name of this codec. The first four characters are // the short name and the string starting at the fifth character // is the long name. // *ppusName = pusCodecName; // // Success. // return(1); } // // Return the name of the artist. // case IOCTL_CODEC_GETARTIST: { unsigned short **ppusName; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // There is no way to store the artist name in an AAC file. // *ppusName = 0; // // Success. // return(1); } // // Return the name of the song // case IOCTL_CODEC_GETTITLE: { unsigned short **ppusName; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // There is no way to store the song title in an AAC file. // *ppusName = 0; // // Success. // return(1); } // // Return the bitrate at which this file is encoded. // case IOCTL_CODEC_GETBITRATE: { unsigned long *pulBitRate; tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent data. // pAAC = (tAAC *)ulParam1; // // The second parameter is a pointer for the bitrate. // pulBitRate = (unsigned long *)ulParam2; // // Return the average bitrate of the file. // *pulBitRate = pAAC->ulBitRate; // // Success. // return(1); } // // Return the sample rate at which this file is encoded. // case IOCTL_CODEC_GETSAMPLERATE: { unsigned long *pulSampleRate; tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent data. // pAAC = (tAAC *)ulParam1; // // The second parameter is a pointer for the sample rate. // pulSampleRate = (unsigned long *)ulParam2; // // Return the sample rate of the file. // *pulSampleRate = pAAC->usSampleRate; // // Success. // return(1); } // // Return the number of channels in the file. // case IOCTL_CODEC_GETCHANNELS: { unsigned long *pulChannels; tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent data. // pAAC = (tAAC *)ulParam1; // // The second parameter is a pointer for the number of channels. // pulChannels = (unsigned long *)ulParam2; // // Return the number of channels in the file. // *pulChannels = pAAC->ucChannels; // // Success. // return(1); } // // Return the length (in milliseconds) of the file. // case IOCTL_CODEC_GETLENGTH: { unsigned long *pulLength; tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent data. // pAAC = (tAAC *)ulParam1; // // The second parameter is a pointer for the number of // milliseconds. // pulLength = (unsigned long *)ulParam2; // // Return the length of the file. // *pulLength = pAAC->ulTimeLength; // // Success. // return(1); } // // Return the current position (in milliseconds) within the file. // case IOCTL_CODEC_GETTIME: { unsigned long *pulTime; tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent data. // pAAC = (tAAC *)ulParam1; // // The second parameter is a pointer for the number of // milliseconds. // pulTime = (unsigned long *)ulParam2; // // Determine the time based on the sample rate. // *pulTime = ((pAAC->ulTimePos / pAAC->usSampleRate) * 1000) + (((pAAC->ulTimePos % pAAC->usSampleRate) * 1000) / pAAC->usSampleRate); // // Success. // return(1); } // // Determine if the given file can be decoded. // case IOCTL_CODEC_QUERY: { tFile *pFile; unsigned char *pucScratch; // // The second parameter is the file to be checked. // pFile = (tFile *)ulParam2; // // The third parameter is a 512 byte scratch buffer. // pucScratch = (unsigned char *)ulParam3; // // Read the first 512 bytes from the file. // FSRead(pFile, pucScratch, 512); // // See if this is an ADIF stream. // if((pucScratch[0] == 'A') && (pucScratch[1] == 'D') && (pucScratch[2] == 'I') && (pucScratch[3] == 'F')) { // // We can decode this file. // return(1); } // // Make sure that the bitstream starts with 0xFFF. // if((pucScratch[0] != 0xff) || ((pucScratch[1] & 0xf0) != 0xf0)) { return(0); } // // The bitstream is a MPEG audio stream, so make sure that the // layer specified is reserved (i.e. AAC). // if((pucScratch[1] & 0x0e) != 0x08) { return(0); } // // Make sure that the file is encoded in the low complexity // profile. // if((pucScratch[2] & 0xc0) != 0x40) { return(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -