00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "mp3_header.h"
00029
00030 #define FRAMES_FLAG 0x0001
00031 #define BYTES_FLAG 0x0002
00032 #define TOC_FLAG 0x0004
00033 #define SCALE_FLAG 0x0008
00034
00035 static int ExtractI4(unsigned char *buf)
00036 {
00037 int x;
00038
00039
00040 x = buf[0];
00041 x <<= 8;
00042 x |= buf[1];
00043 x <<= 8;
00044 x |= buf[2];
00045 x <<= 8;
00046 x |= buf[3];
00047
00048 return x;
00049 }
00050
00051 uint32 fto_nearest_i(float f)
00052 {
00053 uint32 i;
00054
00055 i = (uint32)f;
00056 if (i < f)
00057 {
00058 f -= i;
00059 if (f >= 0.5)
00060 return i+1;
00061 else
00062 return i;
00063 }
00064 else
00065 return i;
00066 }
00067
00068 uint16 calcCRC(char *pFrame, size_t audiodatasize)
00069 {
00070 size_t icounter;
00071 int tmpchar, crcmask, tmpi;
00072 uint16 crc = 0xffff;
00073
00074 for (icounter = 2; icounter < audiodatasize; ++icounter)
00075 {
00076 if (icounter != 4 && icounter != 5)
00077 {
00078 crcmask = 1 << 8;
00079 tmpchar = pFrame[icounter];
00080 while (crcmask >>= 1)
00081 {
00082 tmpi = crc & 0x8000;
00083 crc <<= 1;
00084 if (!tmpi ^ !(tmpchar & crcmask))
00085 crc ^= 0x8005;
00086 }
00087 }
00088 }
00089 crc &= 0xffff;
00090 return crc;
00091 }
00092
00093 void Mp3Info::Clean()
00094 {
00095 if (_mp3_header_output != NULL)
00096 delete _mp3_header_output;
00097 _mp3_header_output = NULL;
00098 }
00099
00100 using namespace dami;
00101
00102 bool Mp3Info::Parse(ID3_Reader& reader, size_t mp3size)
00103 {
00104 MP3_BitRates _mp3_bitrates[2][3][16] =
00105 {
00106 {
00107 {
00108 MP3BITRATE_NONE,
00109 MP3BITRATE_32K,
00110 MP3BITRATE_64K,
00111 MP3BITRATE_96K,
00112 MP3BITRATE_128K,
00113 MP3BITRATE_160K,
00114 MP3BITRATE_192K,
00115 MP3BITRATE_224K,
00116 MP3BITRATE_256K,
00117 MP3BITRATE_288K,
00118 MP3BITRATE_320K,
00119 MP3BITRATE_352K,
00120 MP3BITRATE_384K,
00121 MP3BITRATE_416K,
00122 MP3BITRATE_448K,
00123 MP3BITRATE_FALSE
00124 },
00125 {
00126 MP3BITRATE_NONE,
00127 MP3BITRATE_32K,
00128 MP3BITRATE_48K,
00129 MP3BITRATE_56K,
00130 MP3BITRATE_64K,
00131 MP3BITRATE_80K,
00132 MP3BITRATE_96K,
00133 MP3BITRATE_112K,
00134 MP3BITRATE_128K,
00135 MP3BITRATE_160K,
00136 MP3BITRATE_192K,
00137 MP3BITRATE_224K,
00138 MP3BITRATE_256K,
00139 MP3BITRATE_320K,
00140 MP3BITRATE_384K,
00141 MP3BITRATE_FALSE
00142 },
00143 {
00144 MP3BITRATE_NONE,
00145 MP3BITRATE_32K,
00146 MP3BITRATE_40K,
00147 MP3BITRATE_48K,
00148 MP3BITRATE_56K,
00149 MP3BITRATE_64K,
00150 MP3BITRATE_80K,
00151 MP3BITRATE_96K,
00152 MP3BITRATE_112K,
00153 MP3BITRATE_128K,
00154 MP3BITRATE_160K,
00155 MP3BITRATE_192K,
00156 MP3BITRATE_224K,
00157 MP3BITRATE_256K,
00158 MP3BITRATE_320K,
00159 MP3BITRATE_FALSE
00160 }
00161 },
00162 {
00163 {
00164 MP3BITRATE_NONE,
00165 MP3BITRATE_32K,
00166 MP3BITRATE_48K,
00167 MP3BITRATE_56K,
00168 MP3BITRATE_64K,
00169 MP3BITRATE_80K,
00170 MP3BITRATE_96K,
00171 MP3BITRATE_112K,
00172 MP3BITRATE_128K,
00173 MP3BITRATE_144K,
00174 MP3BITRATE_160K,
00175 MP3BITRATE_176K,
00176 MP3BITRATE_192K,
00177 MP3BITRATE_224K,
00178 MP3BITRATE_256K,
00179 MP3BITRATE_FALSE
00180 },
00181 {
00182 MP3BITRATE_NONE,
00183 MP3BITRATE_8K,
00184 MP3BITRATE_16K,
00185 MP3BITRATE_24K,
00186 MP3BITRATE_32K,
00187 MP3BITRATE_40K,
00188 MP3BITRATE_48K,
00189 MP3BITRATE_56K,
00190 MP3BITRATE_64K,
00191 MP3BITRATE_80K,
00192 MP3BITRATE_96K,
00193 MP3BITRATE_112K,
00194 MP3BITRATE_128K,
00195 MP3BITRATE_144K,
00196 MP3BITRATE_160K,
00197 MP3BITRATE_FALSE
00198 },
00199 {
00200 MP3BITRATE_NONE,
00201 MP3BITRATE_8K,
00202 MP3BITRATE_16K,
00203 MP3BITRATE_24K,
00204 MP3BITRATE_32K,
00205 MP3BITRATE_40K,
00206 MP3BITRATE_48K,
00207 MP3BITRATE_56K,
00208 MP3BITRATE_64K,
00209 MP3BITRATE_80K,
00210 MP3BITRATE_96K,
00211 MP3BITRATE_112K,
00212 MP3BITRATE_128K,
00213 MP3BITRATE_144K,
00214 MP3BITRATE_160K,
00215 MP3BITRATE_FALSE
00216 }
00217 }
00218 };
00219
00220 Mp3_Frequencies _mp3_frequencies[4][4] =
00221 {
00222 { MP3FREQUENCIES_11025HZ, MP3FREQUENCIES_12000HZ, MP3FREQUENCIES_8000HZ,MP3FREQUENCIES_Reserved },
00223 { MP3FREQUENCIES_Reserved, MP3FREQUENCIES_Reserved, MP3FREQUENCIES_Reserved, MP3FREQUENCIES_Reserved},
00224 { MP3FREQUENCIES_22050HZ, MP3FREQUENCIES_24000HZ, MP3FREQUENCIES_16000HZ, MP3FREQUENCIES_Reserved },
00225 { MP3FREQUENCIES_44100HZ, MP3FREQUENCIES_48000HZ, MP3FREQUENCIES_32000HZ, MP3FREQUENCIES_Reserved }
00226 };
00227
00228 _mp3_header_internal *_tmpheader;
00229
00230 const size_t HEADERSIZE = 4;
00231 char buf[HEADERSIZE+1];
00232 ID3_Reader::pos_type beg = reader.getCur() ;
00233 ID3_Reader::pos_type end = beg + HEADERSIZE ;
00234 reader.setCur(beg);
00235 int bitrate_index;
00236
00237 _mp3_header_output->layer = MPEGLAYER_FALSE;
00238 _mp3_header_output->version = MPEGVERSION_FALSE;
00239 _mp3_header_output->bitrate = MP3BITRATE_FALSE;
00240 _mp3_header_output->channelmode = MP3CHANNELMODE_FALSE;
00241 _mp3_header_output->modeext = MP3MODEEXT_FALSE;
00242 _mp3_header_output->emphasis = MP3EMPHASIS_FALSE;
00243 _mp3_header_output->crc = MP3CRC_MISMATCH;
00244 _mp3_header_output->frequency = 0;
00245 _mp3_header_output->framesize = 0;
00246 _mp3_header_output->frames = 0;
00247 _mp3_header_output->time = 0;
00248 _mp3_header_output->vbr_bitrate = 0;
00249
00250 reader.readChars(buf, HEADERSIZE);
00251 buf[HEADERSIZE]='\0';
00252
00253
00254 if (((buf[0] & 0xFF) != 0xFF) || ((buf[1] & 0xE0) != 0xE0))
00255 {
00256 this->Clean();
00257 return false;
00258 }
00259
00260 _tmpheader = reinterpret_cast<_mp3_header_internal *>(buf);
00261
00262 bitrate_index = 0;
00263 switch (_tmpheader->id)
00264 {
00265 case 3:
00266 _mp3_header_output->version = MPEGVERSION_1;
00267 bitrate_index = 0;
00268 break;
00269 case 2:
00270 _mp3_header_output->version = MPEGVERSION_2;
00271 bitrate_index = 1;
00272 break;
00273 case 1:
00274 this->Clean();
00275 return false;
00276 break;
00277 case 0:
00278 _mp3_header_output->version = MPEGVERSION_2_5;
00279 bitrate_index = 1;
00280 break;
00281 default:
00282 this->Clean();
00283 return false;
00284 break;
00285 };
00286
00287 switch (_tmpheader->layer)
00288 {
00289 case 3:
00290 _mp3_header_output->layer = MPEGLAYER_I;
00291 break;
00292 case 2:
00293 _mp3_header_output->layer = MPEGLAYER_II;
00294 break;
00295 case 1:
00296 _mp3_header_output->layer = MPEGLAYER_III;
00297 break;
00298 case 0:
00299 this->Clean();
00300 return false;
00301 break;
00302 default:
00303 this->Clean();
00304 return false;
00305 break;
00306 };
00307
00308
00309 _mp3_header_output->bitrate = _mp3_bitrates[bitrate_index][3-_tmpheader->layer][_tmpheader->bitrate_index];
00310 if (_mp3_header_output->bitrate == MP3BITRATE_FALSE)
00311 {
00312 this->Clean();
00313 return false;
00314 }
00315 _mp3_header_output->frequency = _mp3_frequencies[_tmpheader->id][_tmpheader->frequency];
00316 if (_mp3_header_output->frequency == MP3FREQUENCIES_Reserved)
00317 {
00318 this->Clean();
00319 return false;
00320 }
00321
00322 _mp3_header_output->privatebit = (bool)_tmpheader->private_bit;
00323 _mp3_header_output->copyrighted = (bool)_tmpheader->copyright;
00324 _mp3_header_output->original = (bool)_tmpheader->original;
00325 _mp3_header_output->crc = (Mp3_Crc)!(bool)_tmpheader->protection_bit;
00326
00327 switch (_tmpheader->mode)
00328 {
00329 case 3:
00330 _mp3_header_output->channelmode = MP3CHANNELMODE_SINGLE_CHANNEL;
00331 break;
00332 case 2:
00333 _mp3_header_output->channelmode = MP3CHANNELMODE_DUAL_CHANNEL;
00334 break;
00335 case 1:
00336 _mp3_header_output->channelmode = MP3CHANNELMODE_JOINT_STEREO;
00337 break;
00338 case 0:
00339 _mp3_header_output->channelmode = MP3CHANNELMODE_STEREO;
00340 break;
00341 default:
00342 this->Clean();
00343 return false;
00344 break;
00345 }
00346
00347 if (_mp3_header_output->channelmode == MP3CHANNELMODE_JOINT_STEREO)
00348 {
00349
00350 switch (_tmpheader->mode_ext)
00351 {
00352 case 3:
00353 _mp3_header_output->modeext = MP3MODEEXT_3;
00354 break;
00355 case 2:
00356 _mp3_header_output->modeext = MP3MODEEXT_2;
00357 break;
00358 case 1:
00359 _mp3_header_output->modeext = MP3MODEEXT_1;
00360 break;
00361 case 0:
00362 _mp3_header_output->modeext = MP3MODEEXT_0;
00363 break;
00364 default:
00365 this->Clean();
00366 return false;
00367 break;
00368 }
00369 }
00370 else
00371 _mp3_header_output->modeext = MP3MODEEXT_FALSE;
00372
00373 switch (_tmpheader->emphasis)
00374 {
00375 case 3:
00376 _mp3_header_output->emphasis = MP3EMPHASIS_CCIT_J17;
00377 break;
00378 case 2:
00379 _mp3_header_output->emphasis = MP3EMPHASIS_Reserved;
00380 break;
00381 case 1:
00382 _mp3_header_output->emphasis = MP3EMPHASIS_50_15MS;
00383 break;
00384 case 0:
00385 _mp3_header_output->emphasis = MP3EMPHASIS_NONE;
00386 break;
00387 default:
00388 this->Clean();
00389 return false;
00390 break;
00391 }
00392
00393
00394 if (_mp3_header_output->bitrate != MP3BITRATE_NONE && _mp3_header_output->frequency > 0)
00395 {
00396
00397 switch(_mp3_header_output->layer)
00398 {
00399 case MPEGLAYER_I:
00400 _mp3_header_output->framesize = 4 * (12 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0));
00401 break;
00402 case MPEGLAYER_II:
00403 _mp3_header_output->framesize = 144 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0);
00404 break;
00405 case MPEGLAYER_III:
00406 if(_mp3_header_output->version == MPEGVERSION_2_5)
00407 _mp3_header_output->framesize = 144 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0);
00408 else
00409 _mp3_header_output->framesize = 72000 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0);
00410 break;
00411 }
00412
00413
00414
00415
00416 }
00417 else
00418 _mp3_header_output->framesize = 0;
00419
00420 const size_t CRCSIZE = 2;
00421 size_t sideinfo_len;
00422
00423 if (_mp3_header_output->version == MPEGVERSION_1)
00424 sideinfo_len = (_mp3_header_output->channelmode == MP3CHANNELMODE_SINGLE_CHANNEL) ? 4 + 17 : 4 + 32;
00425 else
00426 sideinfo_len = (_mp3_header_output->channelmode == MP3CHANNELMODE_SINGLE_CHANNEL) ? 4 + 9 : 4 + 17;
00427
00428 int vbr_header_offest = beg + sideinfo_len;
00429 int vbr_frames = 0;
00430
00431 sideinfo_len += 2;
00432
00433 if ((_mp3_header_output->crc == MP3CRC_OK) && mp3size < sideinfo_len)
00434 _mp3_header_output->crc = MP3CRC_ERROR_SIZE;
00435
00436 if (_mp3_header_output->crc == MP3CRC_OK)
00437 {
00438 char audiodata[38 + 1];
00439 uint16 crc16;
00440 uint16 crcstored;
00441
00442 _mp3_header_output->crc = MP3CRC_MISMATCH;
00443
00444 reader.setCur(beg);
00445
00446 reader.readChars(audiodata, sideinfo_len);
00447 audiodata[sideinfo_len] = '\0';
00448
00449 crc16 = calcCRC(audiodata, sideinfo_len);
00450
00451 beg = end;
00452 end = beg + CRCSIZE;
00453
00454 reader.setCur(beg);
00455 crcstored = (uint16)io::readBENumber(reader, CRCSIZE);
00456
00457
00458
00459 if (crcstored == crc16)
00460 _mp3_header_output->crc = MP3CRC_OK;
00461 }
00462
00463
00464
00465
00466
00467 const size_t VBR_HEADER_MIN_SIZE = 8;
00468 const size_t VBR_HEADER_MAX_SIZE = 116;
00469
00470 if (mp3size >= vbr_header_offest + VBR_HEADER_MIN_SIZE)
00471 {
00472 char vbrheaderdata[VBR_HEADER_MAX_SIZE+1];
00473 unsigned char *pvbrdata = (unsigned char *)vbrheaderdata;
00474 int vbr_filesize = 0;
00475 int vbr_scale = 0;
00476 int vbr_flags = 0;
00477
00478
00479
00480
00481 beg = vbr_header_offest;
00482 reader.setCur(beg);
00483 reader.readChars(vbrheaderdata, VBR_HEADER_MIN_SIZE);
00484 vbrheaderdata[VBR_HEADER_MIN_SIZE] = '\0';
00485
00486 if (pvbrdata[0] == 'X' &&
00487 pvbrdata[1] == 'i' &&
00488 pvbrdata[2] == 'n' &&
00489 pvbrdata[3] == 'g')
00490 {
00491
00492 pvbrdata += 4;
00493 vbr_flags = ExtractI4(pvbrdata);
00494 pvbrdata += 4;
00495
00496
00497 int vbr_header_size = VBR_HEADER_MIN_SIZE
00498 + ((vbr_flags & FRAMES_FLAG)? 4:0)
00499 + ((vbr_flags & BYTES_FLAG)? 4:0)
00500 + ((vbr_flags & TOC_FLAG)? 100:0)
00501 + ((vbr_flags & SCALE_FLAG)? 4:0);
00502
00503 if (mp3size >= vbr_header_offest + vbr_header_size)
00504 {
00505 reader.readChars(&vbrheaderdata[VBR_HEADER_MIN_SIZE], vbr_header_size - VBR_HEADER_MIN_SIZE);
00506 vbrheaderdata[vbr_header_size] = '\0';
00507
00508
00509
00510 if (vbr_flags & FRAMES_FLAG)
00511 {
00512 vbr_frames = ExtractI4(pvbrdata);
00513 pvbrdata +=4;
00514 }
00515
00516 if (vbr_flags & BYTES_FLAG)
00517 {
00518 vbr_filesize = ExtractI4(pvbrdata);
00519 pvbrdata +=4;
00520 }
00521
00522 if (vbr_flags & TOC_FLAG)
00523 {
00524
00525
00526
00527
00528 pvbrdata +=100;
00529 }
00530
00531 if (vbr_flags & SCALE_FLAG)
00532 {
00533 vbr_scale = ExtractI4(pvbrdata);
00534 pvbrdata +=4;
00535 }
00536
00537 if (vbr_frames > 0)
00538 {
00539 _mp3_header_output->vbr_bitrate = (((vbr_filesize!=0) ? vbr_filesize : mp3size) / vbr_frames) * _mp3_header_output->frequency / 144;
00540 _mp3_header_output->vbr_bitrate -= _mp3_header_output->vbr_bitrate%1000;
00541 }
00542 }
00543 }
00544 }
00545
00546 if (_mp3_header_output->framesize > 0 && mp3size >= _mp3_header_output->framesize)
00547 {
00548 if (vbr_frames == 0)
00549 _mp3_header_output->frames = fto_nearest_i((float)mp3size / _mp3_header_output->framesize);
00550 else
00551 _mp3_header_output->frames = vbr_frames;
00552
00553
00554 if (_mp3_header_output->vbr_bitrate == 0)
00555 _mp3_header_output->time = fto_nearest_i( (float)mp3size / (_mp3_header_output->bitrate / 8) );
00556 else
00557 _mp3_header_output->time = fto_nearest_i( (float)mp3size / (_mp3_header_output->vbr_bitrate / 8) );
00558 }
00559 else
00560 {
00561 _mp3_header_output->frames = 0;
00562 _mp3_header_output->time = 0;
00563 }
00564
00565 return true;
00566 }
00567
00568