📄 aac.c
字号:
} // // Make sure that a valid sample rate is specified (we do not // support 64kHz, 88.2kHz, and 96kHz). // if(((pucScratch[2] & 0x3c) < 0x0c) || ((pucScratch[2] & 0x3c) > 0x2c)) { return(0); } // // We can decode this file. // return(1); } // // Prepare the codec to encode or decode a file. // case IOCTL_CODEC_OPEN: { tAAC *pAAC; // // If we are being asked to encode an AAC file, then return a // failure since we can only decode AAC. // if(ulParam3 & CODEC_OPEN_ENCODE) { return(0); } // // The first parameter is a pointer to the AAC persistent state. // pAAC = (tAAC *)ulParam1; // // Make sure that we have enough memory for this decoder. // if((ulParam1 + sizeof(tAAC) + AAC_DecoderSize) > ulExtentOfRAM) { return(0); } // // Determine the pointer to the AAC decoder library's persistent // state. // pAAC->pAACInstance = (tAAC_Decoder *)(ulParam1 + sizeof(tAAC)); // // Initialize the bitstream structure. // pAAC->sBS.DataEnd = (unsigned long *)(pAAC->pcEncodedData + 2048); pAAC->sBS.DataStart = (unsigned long *)pAAC->pcEncodedData; pAAC->sBS.DataIn = (unsigned long *)pAAC->pcEncodedData; // // Initialize the AAC library. // if(AAC_Initialise(pAAC->pAACInstance, &(pAAC->sBS), &(pAAC->sHdr), eAAC_44100) != eAAC_NoError) { return(0); } // // Save the pointer to the file structure. // pAAC->pFile = (tFile *)ulParam4; // // Read the first 2K of data from the file. // FSReadBS(pAAC->pFile, pAAC->pcEncodedData, 2048); // // See if this is an ADIF stream. // if((pAAC->pcEncodedData[3] == 'A') && (pAAC->pcEncodedData[2] == 'D') && (pAAC->pcEncodedData[1] == 'I') && (pAAC->pcEncodedData[0] == 'F')) { // // This is an ADIF stream, so there is no fixed frame header. // pAAC->ulHeader = 0; } // // See if this is an ADTS stream. // else if((pAAC->pcEncodedData[3] == 0xff) && ((pAAC->pcEncodedData[2] & 0xfe) == 0xf8)) { // // This is an ADTS stream, so remember the fixed frame header. // pAAC->ulHeader = (pAAC->pcEncodedData[3] << 24) | (pAAC->pcEncodedData[2] << 16) | (pAAC->pcEncodedData[1] << 8) | (pAAC->pcEncodedData[0] & 0xf0); } // // We can not decode this stream if it does not have either an // ADIF or ADTS header. // else { return(0); } // // Decode the bitstream header. // if(AAC_DecodeHeader(pAAC->pAACInstance, &(pAAC->sBS), &(pAAC->sHdr)) != eAAC_NoError) { return(0); } // // Get the number of channels, sample rate and bit rate of the // file. // pAAC->ucChannels = pAAC->sHdr.NumberOfChannels; pAAC->usSampleRate = ulSRMap[pAAC->sHdr.Frequency]; if((pAAC->sHdr.BitstreamFormat == eAAC_ADIF) && (pAAC->sHdr.BitstreamType == eAAC_ConstantRate)) { pAAC->ulBitRate = pAAC->sHdr.BitRate; } else { pAAC->ulBitRate = 0; } // // Make sure that the stream has only one or two channels. // if(pAAC->ucChannels > 2) { return(0); } // // Get the length of the file. // if(pAAC->ulBitRate) { pAAC->ulTimeLength = (((FSLength(pAAC->pFile) * 8) / pAAC->ulBitRate) * 1000) + ((((FSLength(pAAC->pFile) * 8) % pAAC->ulBitRate) * 1000) / pAAC->ulBitRate); } else { pAAC->ulTimeLength = 0; } // // The position is zero. // pAAC->ulTimePos = 0; // // There is no output buffer. // pAAC->pOutput = 0; // // Success. // return(1); } // // Set the output buffer for the decoder. // case IOCTL_CODEC_SETBUFFER: { tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent state. // pAAC = (tAAC *)ulParam1; // // The second parameter is a pointer to the output buffer. // pAAC->pOutput = (BufferState *)ulParam2; // // Provide the output buffer with our data buffers. // if(pAAC->ucChannels == 2) { BufferSetBuffer(pAAC->pOutput, pAAC->psLeft, pAAC->psRight, AAC_MAX_PCM_LENGTH + AAC_MAX_PCM_LENGTH); } else { BufferSetBuffer(pAAC->pOutput, pAAC->psLeft, pAAC->psLeft, AAC_MAX_PCM_LENGTH + AAC_MAX_PCM_LENGTH); } // // Success. // return(1); } // // Determine if the next frame of data can be decoded. // case IOCTL_CODEC_CAN_DECODE: { tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent state. // pAAC = (tAAC *)ulParam1; // // See if there is space available for decoding the next frame. // if(BufferSpaceAvailable(pAAC->pOutput) < AAC_MAX_PCM_LENGTH) { // // There is not enough space available, so we can not decode // the next frame. // return(0); } // // We can decode the next frame. // return(1); } // // Decode a frame of data. // case IOCTL_CODEC_DECODE: { tAAC *pAAC; short *psBuffers[3]; long lLength; // // The first parameter is a pointer to the AAC persistent state. // pAAC = (tAAC *)ulParam1; // // Wait until there is space in the output buffer. This tells us // when it is OK to write more data into the output buffer. // while(BufferSpaceAvailable(pAAC->pOutput) < AAC_MAX_PCM_LENGTH) { // // Busy wait until space is available. // } // // Get a pointer to the available space in the output buffer. // BufferGetWritePointer(pAAC->pOutput, &psBuffers[0], &psBuffers[1], &lLength); psBuffers[2] = 0; // // Decode the data frame. // if(AAC_DecodeDataBlock(pAAC->pAACInstance, &(pAAC->sBS), &(pAAC->sHdr), psBuffers) != eAAC_NoError) { // // We could not decode the frame, so return an error. // return(0); } // // Update the output buffer's write pointer. // BufferUpdateWritePointer(pAAC->pOutput, AAC_MAX_PCM_LENGTH); // // Increment the time based on the number of samples. // pAAC->ulTimePos += AAC_MAX_PCM_LENGTH; // // See if we can read more data from the file. // while((pAAC->sBS.DataOut < pAAC->sBS.DataIn) || (((long)pAAC->sBS.DataOut - (long)pAAC->sBS.DataIn) >= 512)) { // // Do we need to read up to the end of the input bitstream // buffer? // if(pAAC->sBS.DataOut < pAAC->sBS.DataIn) { // // Read up to the end of the bitstream buffer. // FSReadBS(pAAC->pFile, pAAC->sBS.DataIn, (long)pAAC->sBS.DataEnd - (long)pAAC->sBS.DataIn); // // Move the write pointer in the bitstream structure. // pAAC->sBS.DataIn = pAAC->sBS.DataStart; } else { // // Determine the number of bytes to read. // lLength = ((long)pAAC->sBS.DataOut - (long)pAAC->sBS.DataIn) & ~0x1ff; // // Read data into the data buffer. // FSReadBS(pAAC->pFile, pAAC->sBS.DataIn, lLength); // // Move the write pointer in the bitstream structure. // pAAC->sBS.DataIn += lLength / 4; } } // // Success. // return(1); } // // Encode a frame of data. // case IOCTL_CODEC_CAN_ENCODE: case IOCTL_CODEC_ENCODE: { // // We don't support encode, so return an error. // return(0); } // // Seek to the specified time position. // case IOCTL_CODEC_SEEK: { tAAC *pAAC; // // The first parameter is a pointer to the AAC persistent state. // pAAC = (tAAC *)ulParam1; // // If we are decoding an ADIF stream, then we can not seek to // non-zero positions. // if((pAAC->ulHeader == 0) && (ulParam2 != 0)) { return(0); } // // If we are seeking to zero, then simply re-position the bitstream // to the beginning. // if(ulParam2 == 0) { // // Seek the file pointer back to the beginning of the file. // FSSeek(pAAC->pFile, 0); // // Read the first 2k of data from the file. // FSReadBS(pAAC->pFile, pAAC->pcEncodedData, 2048); // // Reset the data write pointer in the bitstream structure. // pAAC->sBS.DataIn = (unsigned long *)pAAC->pcEncodedData; // // Initialize the AAC library. // AAC_Initialise(pAAC->pAACInstance, &(pAAC->sBS), &(pAAC->sHdr), eAAC_44100); // // The new position is zero. // pAAC->ulTimePos = 0; // // Success. // return(1); } // // We don't support other seeks yet. // return(0); } // // Cleanup after the codec. // case IOCTL_CODEC_CLOSE: { // // There's nothing to do, so return success. // return(1); } // // We should never get here, but just in case... // default: { // // Return a failure. // return(0); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -