📄 mp3.c
字号:
//// MP3DecodeID3Tag sees if the MP3 stream has an ID3 tag. If found, the// song title and artist is extracted from the tag.////****************************************************************************static voidMP3DecodeID3Tag(tMP3 *pMP3){ unsigned long ulDataStart, ulLength; // // Save the original position and length of the MP3 data. // ulDataStart = pMP3->ulFirstFrame; ulLength = pMP3->ulLength + pMP3->ulFirstFrame; // // See if the file contains any ID3 tags. If it does, ulFirstFrame and // ulLength in the MP3 persistent data structure will be updated to reflect // the start and length of the actual MP3 data, without the ID3 tags. // ID3FindTags(pMP3->pFile, &pMP3->ulFirstFrame, &pMP3->ulLength, (unsigned char *)pMP3->pcEncodedData); // // Get the value of the "TPE1" tag, which contains the name of the artist. // if(ID3GetTagValue(pMP3->pFile, ulDataStart, ulLength, (unsigned char *)pMP3->pcEncodedData, "TPE1", pMP3->pusArtist, 64) == 0) { pMP3->pusArtist[0] = 0; } // // Get the value of the "TIT2" tag, which contains the name of the song. // if(ID3GetTagValue(pMP3->pFile, ulDataStart, ulLength, (unsigned char *)pMP3->pcEncodedData, "TIT2", pMP3->pusTitle, 64) == 0) { pMP3->pusTitle[0] = 0; }}//****************************************************************************//// Determines if the given file is a MP3 file, and returns the offset of the// first frame if so.////****************************************************************************static unsigned longMP3IsMP3File(tFile *pFile, unsigned char *pucScratch, unsigned long ulOffset){ unsigned long ulSamplesPerFrame, ulSampleRate, ulBitRate, ulFrameLength; unsigned long ulPos, ulCount, ulLoop, ulHdr1, ulHdr2, ulNext; unsigned char pucBuffer[16]; // // Seek to the start of the file data. // FSSeek(pFile, ulOffset & ~511); // // Read 512 bytes from the file. // FSRead(pFile, pucScratch, 512); // // Get the starting offset of the data in the buffer. // ulPos = ulOffset & 511; // // See if there are 10 bytes of valid data in the buffer. // if((ulPos + 10) > 512) { // // Get the count of valid bytes in the buffer. // ulCount = 512 - ulPos; // // Copy the valid bytes from the buffer into our temporary buffer. // memcpy(pucBuffer, pucScratch + ulPos, ulCount); // // Read the next 512 bytes from the file. // FSRead(pFile, pucScratch, 512); // // Copy the next set of valid bytes from the buffer into our temporary // buffer. // memcpy(pucBuffer + ulCount, pucScratch, 16 - ulCount); } else { // // There are 10 bytes of valid data in the buffer, so simply copy them // into our temporary buffer. // memcpy(pucBuffer, pucScratch + ulPos, 16); } // // See if this is a valid ID3 V2 tag. // ulCount = ID3IsV2Tag(pucBuffer); if(ulCount != 0) { // // There is an ID3 V2 tag, so skip past it. // ulOffset += ulCount + 10; } // // Seek to the start of the MP3 stream. // FSSeek(pFile, ulOffset & ~511); // // Read 512 bytes from the file. // FSRead(pFile, pucScratch, 512); // // Get the starting offset of the data in the buffer. // ulPos = ulOffset & 511; // // Get the offset of the start of data in the buffer. // ulOffset &= ~511; // // Examine the next 2048 bytes of the file (which is four 512 byte chunks) // looking for a frame header. // for(ulLoop = 4; ; ulPos++) { // // See if there are 4 bytes of valid data in the buffer. // if((ulPos + 4) > 512) { // // If we're examined 2048 bytes and not found a frame header then // we will not be able to decode this file. // if(ulLoop == 0) { return(-1); } // // Get the count of valid bytes in the buffer. // ulCount = 512 - ulPos; // // Copy the valid bytes from the buffer into our temporary buffer. // memcpy(pucBuffer, pucScratch + ulPos, ulCount); // // Read the next 512 bytes from the file. // FSRead(pFile, pucScratch, 512); // // Indicate the number of bytes in the temporary buffer. // ulPos = 0 - ulCount; // // Update the offset of the start of data in the buffer. // ulOffset += 512; // // Decrement the count of pages to search. // ulLoop--; } // // If there are residual bytes in the temporary buffer, then // concatenate them with the bytes from the beginning of the current // block. // if(ulPos > 512) { // // Get the first byte from the temporary buffer. // ulHdr1 = pucBuffer[0 - ulPos] << 24; // // See if this is the last byte in the temporary buffer. // if((ulPos + 1) == 0) { // // This was the last byte in the temporary buffer, so get the // remaining three bytes from the beginning of the current // block. // ulHdr1 |= ((pucScratch[0] << 16) | (pucScratch[1] << 8) | pucScratch[2]); } else { // // There is at least one more byte in the temporary buffer, so // get the second byte from the temporary buffer. // ulHdr1 |= pucBuffer[1 - ulPos] << 16; // // See if this is the last byte in the temporary buffer. // if((ulPos + 2) == 0) { // // This was the last byte in the temporary buffer, so get // the remaining two bytes from the beginning of the // current block. // ulHdr1 |= ((pucScratch[0] << 8) | pucScratch[1]); } else { // // There is one more byte in the temporary buffer, so get // the last byte from the temporary buffer and the first // byte from the current block. // ulHdr1 |= ((pucBuffer[2 - ulPos] << 8) | pucScratch[0]); } } } else { // // Get the next four bytes from the current block. // ulHdr1 = ((pucScratch[ulPos] << 24) | (pucScratch[ulPos + 1] << 16) | (pucScratch[ulPos + 2] << 8) | pucScratch[ulPos + 3]); } // // See if this word starts with 0xFFE, which is the frame sync for MPEG // audio. // if((ulHdr1 & 0xffe00000) != 0xffe00000) { continue; } // // See that a valid MPEG version was specified. // if((ulHdr1 & 0x00180000) == 0x00080000) { continue; } // // Make sure that the file is encoded with layer 3. // if((ulHdr1 & 0x00060000) != 0x00020000) { continue; } // // Make sure that a valid bit rate is specified. // if((ulHdr1 & 0x0000f000) == 0x0000f000) { continue; } // // Make sure that a valid sample rate is specified. // if((ulHdr1 & 0x00000c00) == 0x00000c00) { continue; } // // If the bit rate index is zero (indicating free-format bit rate), we // simply assume that this is a valid frame header in a valid file. // if((ulHdr1 & 0x0000f000) == 0x00000000) { return(ulOffset + ulPos); } // // Determine if this frame is MPEG-1 or MPEG-2/2.5. // if((ulHdr1 & 0x00080000) == 0x00080000) { // // This frame is MPEG-1, which has 1152 samples per frame. // ulSamplesPerFrame = 1152; // // Get the sample rate of this frame. // ulSampleRate = usSRMap[((ulHdr1 & 0x00000c00) >> 10) + 8]; // // Get the bit rate of this frame. // ulBitRate = usBRMap[((ulHdr1 & 0x0000f000) >> 12) + 16]; } else { // // This frame is MPEG-2/2.5, which has 576 samples per frame. // ulSamplesPerFrame = 576; // // Determine if this frame is MPEG-2 or MPEG-2.5. // if((ulHdr1 & 0x00100000) == 0x00100000) { // // This frame is MPEG-2. Get the sample rate of this frame. // ulSampleRate = usSRMap[((ulHdr1 & 0x00000c00) >> 10) + 4]; } else { // // This frame is MPEG-2.5. Get the sample rate of this frame. // ulSampleRate = usSRMap[(ulHdr1 & 0x00000c00) >> 10]; } // // Get the bit rate of this frame. // ulBitRate = usBRMap[(ulHdr1 & 0x0000f000) >> 12]; } // // Determine the length of this frame. // ulFrameLength = (ulBitRate * 125 * ulSamplesPerFrame) / ulSampleRate; if(ulHdr1 & 0x00000200) { ulFrameLength++; } // // Determine the offset of the next frame header. // ulNext = ulOffset + ulPos + ulFrameLength; // // Determine if the next frame header is in the currently read portion // of the file. // if((ulNext - ulOffset) >= 512) { // // Seek to the position within the file that contains the next // frame header. // FSSeek(pFile, ulNext & ~511); // // Read the 512 bytes from the file. // FSRead(pFile, pucScratch, 512); } // // Get the offset into the buffer of the next frame header. // ulNext &= 511; // // Get the frame header from the buffer. Note that this could read // past the end of the buffer by three bytes. // ulHdr2 = ((pucScratch[ulNext] << 24) | (pucScratch[ulNext + 1] << 16) | (pucScratch[ulNext + 2] << 8) | pucScratch[ulNext + 3]); // // See if the next frame header wraps into the next page of the file. // if(ulNext > 508) { // // Read the next 512 bytes from the file. // FSRead(pFile, pucScratch, 512); // // Determine how many bytes to replace from the newly read page. // switch(ulNext) { // // We have three valid bytes from the previous page. // case 509: { // // Mask off the valid bytes from the previous page. // ulHdr2 &= 0xffffff00; // // Add in the new byte from this page. // ulHdr2 |= pucScratch[0]; // // We're done. // break; } // // We have two valid bytes from the previous page. // case 510: { // // Mask off the valid bytes from the previous page. // ulHdr2 &= 0xffff0000; // // Add in the new bytes from this page. // ulHdr2 |= (pucScratch[0] << 8) | pucScratch[1]; // // We're done. // break; } // // We have one valid byte from the previous page. // case 511: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -