00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <assert.h>
00021 #include "mpeg.h"
00022
00023
00033 bool MPEG_CheckHeader(unsigned long header)
00034 {
00035 if (((header>>21) & 2047) != 2047)
00036 return false;
00037 if (((header>>19) & 3) == 1)
00038 return false;
00039 if (((header>>17) & 3) == 0)
00040 return false;
00041 if (((header>>12) & 15) == 0 ||
00042 ((header>>12) & 15) == 15)
00043 return false;
00044 if (((header>>10) & 3) == 3)
00045 return false;
00046 if (((header>> 0) & 3) == 2)
00047 return false;
00048 return true;
00049 }
00050
00051
00061 bool MPEG_FindHeader( char *buffer, unsigned buflen,
00062 int numHeads )
00063 {
00064 return false;
00065 }
00066
00067
00076 bool MPEG_ParseHeader(unsigned long header, FrameInfo *info)
00077 {
00078 const int ids[4] = { 25, 0, 2, 1 };
00079 const int layers[4] = { 0, 3, 2, 1 };
00080 const long mp1tab[4][16] = { {0},
00081 { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000,
00082 256000, 288000, 320000, 352000, 384000, 416000, 448000, -1 },
00083 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000,
00084 128000, 160000, 192000, 224000, 256000, 320000, 384000, -1 },
00085 { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000,
00086 112000, 128000, 160000, 192000, 224000, 256000, 320000, -1 }
00087 };
00088 const long mp2tab[4][16] = { {0},
00089 { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000,
00090 128000, 144000, 160000, 176000, 192000, 224000, 256000, -1 },
00091 { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000,
00092 64000, 80000, 96000, 112000, 128000, 144000, 160000, -1 },
00093 { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000,
00094 64000, 80000, 96000, 112000, 128000, 144000, 160000, -1 },
00095 };
00096 const long freqs[4][4] = {
00097 { 11025, 12000, 8000, 0},
00098 { 0, 0, 0, 0},
00099 { 22050, 24000, 16000, 0},
00100 { 44100, 48000, 32000, 0}
00101 };
00102
00103 memset(info, 0, sizeof(FrameInfo));
00104 if (!MPEG_CheckHeader(header))
00105 return false;
00106
00107 info->id = ids[(header>>19) & 3];
00108 info->layer = layers[(header>>17) & 3];
00109 info->mode = (header>>6) & 3;
00110 info->extension = (header>>4) & 3;
00111 info->emphasis = (header>>0) & 3;
00112 info->crc = !((header>>16) & 1);
00113 info->pad = (header>>9) & 1;
00114 info->priv = (header>>8) & 1;
00115 info->copyright = (header>>3) & 1;
00116 info->original = (header>>2) & 1;
00117 info->frequency = freqs[(header>>19) & 3][(header>>10) & 3];
00118
00119 if (info->id == 1)
00120 info->bitrate = mp1tab[info->layer][(header>>12) & 15];
00121 else
00122 info->bitrate = mp2tab[info->layer][(header>>12) & 15];
00123
00124 if (info->layer == 1) {
00125 info->length = 48 * info->bitrate/info->frequency;
00126 info->length += info->pad ? 4:0;
00127 } else {
00128 info->length = 144 * info->bitrate/info->frequency;
00129 info->length += info->pad ? 1:0;
00130 }
00131 info->length += info->crc ? 2:0;
00132 return true;
00133 }
00134
00135
00136 char *MPEG_HeaderToString(unsigned long header)
00137 {
00138 static char buf[40];
00139 const char *mode[] = {"Stereo", "J-Stereo", "DualChn", "Mono"};
00140
00141 FrameInfo info;
00142 if (!MPEG_ParseHeader(header, &info))
00143 return "invalid header.";
00144
00145 assert(
00146 sprintf(buf, "MP%uL%u, %3ldkb, %2ldkHz, %s %s",
00147 info.id, info.layer,
00148 info.bitrate/1000, info.frequency/1000,
00149 mode[info.mode], info.crc ? "CRC" : "")
00150 < sizeof(buf)
00151 );
00152
00153 return buf;
00154 }