23. oktober 2002 - 14:38
#1
Følgende kode tolker header informationen fra en MP3 fil:
#include <conio.h>
#include <string.h>
#include <stdio.h>
#define bool int
// MP3 file decoding.
unsigned long bithdr;
int getFrameSync() { return ((bithdr>>21) & 2047); };
int getVersionIndex() { return ((bithdr>>19) & 3); };
int getLayerIndex() { return ((bithdr>>17) & 3); };
int getProtectionBit() { return ((bithdr>>16) & 1); };
int getBitrateIndex() { return ((bithdr>>12) & 15); };
int getFrequencyIndex(){ return ((bithdr>>10) & 3); };
int getPaddingBit() { return ((bithdr>> 9) & 1); };
int getPrivateBit() { return ((bithdr>> 8) & 1); };
int getModeIndex() { return ((bithdr>> 6) & 3); };
int getModeExtIndex() { return ((bithdr>> 4) & 3); };
int getCoprightBit() { return ((bithdr>> 3) & 1); };
int getOrginalBit() { return ((bithdr>> 2) & 1); };
int getEmphasisIndex() { return ((bithdr ) & 3); };
void loadHeader(char c[4]) {
// Turn the four bytes into a unsigned long.
bithdr = (unsigned long)( ( (c[0] & 255) << 24) |
( (c[1] & 255) << 16) |
( (c[2] & 255) << 8) |
( (c[3] & 255) )
);
} // Load header.
bool isValidHeader(void) {
// Check that valid MP3 header.
return ( ((getFrameSync() & 2047)==2047) &&
((getVersionIndex() & 3)!= 1) &&
((getLayerIndex() & 3)!= 0) &&
// due to lack of support of the .mp3 format
// no "public" .mp3's should contain information
// like this anyway... :)
((getBitrateIndex() & 15)!= 0) &&
((getBitrateIndex() & 15)!= 15) &&
((getFrequencyIndex() & 3)!= 3) &&
((getEmphasisIndex() & 3)!= 2) );
} // isValidHeader
// this returns the MPEG version [1.0-2.5]
float getVersion() {
float table[4] = {
2.5, 0.0, 2.0, 1.0
};
// return modified value
return table[getVersionIndex()];
} // getVersion
// this returns the Layer [1-3]
int getLayer() {
return ( 4 - getLayerIndex() );
} // getLayer
int getBitrate() {
const int table[2][3][16] = {
{ //MPEG 2 & 2.5
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, //Layer III
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, //Layer II
{0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0} //Layer I
},{ //MPEG 1
{0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}, //Layer III
{0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, //Layer II
{0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,0} //Layer I
}
};
// the bitrate is not only dependent of the bitrate index,
// the bitrate also varies with the MPEG version and Layer version
return table[(getVersionIndex() & 1)][(getLayerIndex() -1)][getBitrateIndex()];
} // getBitrate
unsigned int getFrequency() {
unsigned int table[4][3] = {
{32000, 16000, 8000}, //MPEG 2.5
{ 0, 0, 0}, //reserved
{22050, 24000, 16000}, //MPEG 2
{44100, 48000, 32000} //MPEG 1
};
// the frequency is not only dependent of the bitrate index,
// the bitrate also varies with the MPEG version
return table[getVersionIndex()][getFrequencyIndex()];
} // getFrequency
char *getMode(void) {
switch(getModeIndex()) {
case 1: return "Joint Stereo";
case 2: return "Dual Channel";
case 3: return "Single Channel";
}
return "Stereo";
} // getMode
int main(int argc, char *argv[])
{
FILE *mp3File;
char mp3Hdr[4];
if (argc < 2
|| (mp3File = fopen(argv[1], "rb")) == NULL
|| fread(mp3Hdr, sizeof(mp3Hdr), 1, mp3File) != 1)
{
cprintf("Too few arguments (%d), non-existing or invalid file.(%s)\r\n",
argc, argv[1]);
return -1;
};
// Check if valid MP3 file.
loadHeader(mp3Hdr);
if (!isValidHeader())
{
cprintf("Header for %s not valid.\r\n", argv[1]);
return -1;
}
// Then display all information about the MP3 file.
cprintf("MP3 information for \'%s\':\r\n", argv[1]);
cprintf("=====================%.*s==\r\n", strlen(argv[1]),
"==============================");
cprintf("Version : %1.1f\r\n", getVersion());
cprintf("Layer : %d\r\n", getLayer());
cprintf("Bit-rate : %u\r\n", getBitrate());
cprintf("Frequency : %u\r\n", getFrequency());
cprintf("Mode : %s\r\n", getMode());
return 0;
} // Main