📄 mp3.c
字号:
// // Mask off the valid byte from the previous page. // ulHdr2 &= 0xff000000; // // Add in the new bytes from this page. // ulHdr2 |= ((pucScratch[0] << 16) | (pucScratch[1] << 8) | pucScratch[2]); // // We're done. // break; } } } // // See if the two headers match. We only compare the sync word, ID, // layer, and sample rate fields (since the others can change from // frame to frame). // if((ulHdr2 & 0xfffe0c00) == (ulHdr1 & 0xfffe0c00)) { // // The two headers match, so return the offset of the first header // as the starting position of MP3 data in the file. // return(ulOffset + ulPos); } // // See if we performed a read to find the next frame header. // if(FSTell(pFile) != (ulOffset + 512)) { // // Seek back to the original file position. // FSSeek(pFile, ulOffset); // // Read 512 bytes from the original file position. // FSRead(pFile, pucScratch, 512); } }}//****************************************************************************//// The codec plug-in entry point for the MP3 decoder.////****************************************************************************unsigned longMP3Ioctl(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 second 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; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)ulParam1; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // Return the name of the artist. // *ppusName = pMP3->pusArtist; // // Success. // return(1); } // // Return the name of the song // case IOCTL_CODEC_GETTITLE: { unsigned short **ppusName; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)ulParam1; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // Return the name of the song. // *ppusName = pMP3->pusTitle; // // Success. // return(1); } // // Return the bitrate at which this file is encoded. // case IOCTL_CODEC_GETBITRATE: { unsigned long *pulBitRate; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)ulParam1; // // The second parameter is a pointer for the bitrate. // pulBitRate = (unsigned long *)ulParam2; // // Return the average bitrate of the file. // *pulBitRate = pMP3->ulBitRate; // // Success. // return(1); } // // Return the sample rate at which this file is encoded. // case IOCTL_CODEC_GETSAMPLERATE: { unsigned long *pulSampleRate; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)ulParam1; // // The second parameter is a pointer for the sample rate. // pulSampleRate = (unsigned long *)ulParam2; // // Return the sample rate of the file. // *pulSampleRate = pMP3->usSampleRate; // // Success. // return(1); } // // Return the number of channels in the file. // case IOCTL_CODEC_GETCHANNELS: { unsigned long *pulChannels; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)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 = pMP3->ucChannels; // // Success. // return(1); } // // Return the length (in milliseconds) of the file. // case IOCTL_CODEC_GETLENGTH: { unsigned long *pulLength; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)ulParam1; // // The second parameter is a pointer for the number of // milliseconds. // pulLength = (unsigned long *)ulParam2; // // Return the length of the file. // *pulLength = pMP3->ulTimeLength; // // Success. // return(1); } // // Return the current position (in milliseconds) within the file. // case IOCTL_CODEC_GETTIME: { unsigned long *pulTime; tMP3 *pMP3; // // The first parameter is a pointer to the MP3 persistent data. // pMP3 = (tMP3 *)ulParam1; // // The second parameter is a pointer for the number of seconds. // pulTime = (unsigned long *)ulParam2; // // Determine the time based on the sample rate. // *pulTime = ((pMP3->ulTimePos / pMP3->usSampleRate) * 1000) + (((pMP3->ulTimePos % pMP3->usSampleRate) * 1000) / pMP3->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; // // Determine if this is a MP3 file. // if(MP3IsMP3File(pFile, pucScratch, ulParam4) == -1) { return(0); } // // This is a MP3 file. // return(1); } // // Prepare the codec to encode or decode a file. // case IOCTL_CODEC_OPEN: { tMP3 *pMP3; // // If we are being asked to encode an MP3 file, then return a // failure since we can only decode MP3. // if(ulParam3 & CODEC_OPEN_ENCODE) { return(0); } // // The first parameter is a pointer to the MP3 persistent state. // pMP3 = (tMP3 *)ulParam1; // // Determine the pointer to the MP3 decoder library's persistent // state. This pointer must be aligned on a 2K byte boundary. // pMP3->pMPEGInstance = (tMPEGInstance *)(((unsigned long)pMP3 + sizeof(tMP3) + 2047) & 0xfffff800); // // Make sure that we have enough memory for this decoder. // if(((unsigned long)pMP3->pMPEGInstance + sizeof(tMPEGInstance)) > ulExtentOfRAM) { return(0); } // // Initialize the MP3 library. // InitMP3Audio(pMP3->pMPEGInstance); // // Save the pointer to the file structure. // pMP3->pFile = (tFile *)ulParam4; // // Save the position of the beginning of the file. // pMP3->ulFirstFrame = ulParam2; // // Get the length of the file. // pMP3->ulLength = FSLength(pMP3->pFile) - pMP3->ulFirstFrame; // // Decode the ID3 tag if it is present. // MP3DecodeID3Tag(pMP3); // // Determine the starting position of the first frame. // pMP3->ulFirstFrame = MP3IsMP3File(pMP3->pFile, (unsigned char *)pMP3->pcEncodedData, pMP3->ulFirstFrame); if(pMP3->ulFirstFrame == -1) { // // We could not find a valid first frame, so return an error. // return(0); } // // Initialize the bitstream. // MP3InitBitstream(pMP3, pMP3->ulFirstFrame); // // Find the first frame of the file. // if(MP3FindNextFrame(pMP3) == 0) { // // If we could not find the first frame of the file, then // return an error. // return(0); } // // Get the sample rate of the file. // pMP3->usSampleRate = usSRMap[pMP3->sHdr.sample_rate]; // // Get the number of channels in the file. // pMP3->ucChannels = pMP3->sHdr.numchans; // // Attempt to decode the VBR header. // if(MP3DecodeVBRHeader(pMP3) == 0) { // // There is no VBR header on this file, so get the actual // bitrate from the sync header. // pMP3->ulBitRate = usBRMap[((pMP3->sHdr.packed_info & 0x00080000) >> 15) | ((pMP3->sHdr.packed_info & 0x0000f000) >> 12)] * 1000; // // If no bitrate is specified, then return an error. // if(pMP3->ulBitRate == 0) { return(0); } // // Indicate that this is not a VBR file. // pMP3->ucIsVBR = 0; } // // Get the length of the file. // pMP3->ulTimeLength = (((pMP3->ulLength * 8) / pMP3->ulBitRate) * 1000) + ((((pMP3->ulLength * 8) % pMP3->ulBitRate) * 1000) / pMP3->ulBitRate);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -