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