30 #define FRAMES_FLAG 0x0001
31 #define BYTES_FLAG 0x0002
32 #define TOC_FLAG 0x0004
33 #define SCALE_FLAG 0x0008
35 static int ExtractI4(
unsigned char *buf)
68 uint16
calcCRC(
char *pFrame,
size_t audiodatasize)
71 int tmpchar, crcmask, tmpi;
74 for (icounter = 2; icounter < audiodatasize; ++icounter)
76 if (icounter != 4 && icounter != 5)
79 tmpchar = pFrame[icounter];
84 if (!tmpi ^ !(tmpchar & crcmask))
95 if (_mp3_header_output !=
NULL)
96 delete _mp3_header_output;
97 _mp3_header_output =
NULL;
100 using namespace dami;
228 _mp3_header_internal *_tmpheader;
230 const size_t HEADERSIZE = 4;
231 char buf[HEADERSIZE+1];
244 _mp3_header_output->frequency = 0;
245 _mp3_header_output->framesize = 0;
246 _mp3_header_output->frames = 0;
247 _mp3_header_output->time = 0;
248 _mp3_header_output->vbr_bitrate = 0;
251 buf[HEADERSIZE]=
'\0';
254 if (((buf[0] & 0xFF) != 0xFF) || ((buf[1] & 0xE0) != 0xE0))
260 _tmpheader =
reinterpret_cast<_mp3_header_internal *
>(buf);
263 switch (_tmpheader->id)
287 switch (_tmpheader->layer)
309 _mp3_header_output->bitrate = _mp3_bitrates[bitrate_index][3-_tmpheader->layer][_tmpheader->bitrate_index];
315 _mp3_header_output->frequency = _mp3_frequencies[_tmpheader->id][_tmpheader->frequency];
322 _mp3_header_output->privatebit = (bool)_tmpheader->private_bit;
323 _mp3_header_output->copyrighted = (
bool)_tmpheader->copyright;
324 _mp3_header_output->original = (bool)_tmpheader->original;
325 _mp3_header_output->crc = (
Mp3_Crc)!(bool)_tmpheader->protection_bit;
327 switch (_tmpheader->mode)
350 switch (_tmpheader->mode_ext)
373 switch (_tmpheader->emphasis)
394 if (_mp3_header_output->bitrate !=
MP3BITRATE_NONE && _mp3_header_output->frequency > 0)
397 switch(_mp3_header_output->layer)
400 _mp3_header_output->framesize = 4 * (12 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0));
403 _mp3_header_output->framesize = 144 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0);
407 _mp3_header_output->framesize = 144 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0);
409 _mp3_header_output->framesize = 72000 * _mp3_header_output->bitrate / _mp3_header_output->frequency + (_tmpheader->padding_bit ? 1 : 0);
420 _mp3_header_output->framesize = 0;
422 const size_t CRCSIZE = 2;
430 int vbr_header_offest = beg + sideinfo_len;
435 if ((_mp3_header_output->crc ==
MP3CRC_OK) && mp3size < sideinfo_len)
438 if (_mp3_header_output->crc ==
MP3CRC_OK)
440 char audiodata[38 + 1];
448 reader.
readChars(audiodata, sideinfo_len);
449 audiodata[sideinfo_len] =
'\0';
451 crc16 =
calcCRC(audiodata, sideinfo_len);
457 crcstored = (uint16)io::readBENumber(reader, CRCSIZE);
461 if (crcstored == crc16)
469 const size_t VBR_HEADER_MIN_SIZE = 8;
470 const size_t VBR_HEADER_MAX_SIZE = 120;
472 if (mp3size >= vbr_header_offest + VBR_HEADER_MIN_SIZE)
474 char vbrheaderdata[VBR_HEADER_MAX_SIZE+1];
475 unsigned char *pvbrdata = (
unsigned char *)vbrheaderdata;
476 int vbr_filesize = 0;
483 beg = vbr_header_offest;
485 reader.
readChars(vbrheaderdata, VBR_HEADER_MIN_SIZE);
486 vbrheaderdata[VBR_HEADER_MIN_SIZE] =
'\0';
488 if (pvbrdata[0] ==
'X' &&
489 pvbrdata[1] ==
'i' &&
490 pvbrdata[2] ==
'n' &&
495 vbr_flags = ExtractI4(pvbrdata);
499 unsigned int vbr_header_size = VBR_HEADER_MIN_SIZE
505 if (mp3size >= vbr_header_offest + vbr_header_size)
507 reader.
readChars(&vbrheaderdata[VBR_HEADER_MIN_SIZE], vbr_header_size - VBR_HEADER_MIN_SIZE);
508 vbrheaderdata[vbr_header_size] =
'\0';
514 vbr_frames = ExtractI4(pvbrdata);
520 vbr_filesize = ExtractI4(pvbrdata);
535 vbr_scale = ExtractI4(pvbrdata);
541 _mp3_header_output->vbr_bitrate = (((vbr_filesize!=0) ? vbr_filesize : mp3size) / vbr_frames) * _mp3_header_output->frequency / 144;
542 _mp3_header_output->vbr_bitrate -= _mp3_header_output->vbr_bitrate%1000;
548 if (_mp3_header_output->framesize > 0 && mp3size >= _mp3_header_output->framesize)
551 _mp3_header_output->frames =
fto_nearest_i((
float)mp3size / _mp3_header_output->framesize);
553 _mp3_header_output->frames = vbr_frames;
556 if (_mp3_header_output->vbr_bitrate == 0)
557 _mp3_header_output->time =
fto_nearest_i( (
float)mp3size / (_mp3_header_output->bitrate / 8) );
559 _mp3_header_output->time =
fto_nearest_i( (
float)mp3size / (_mp3_header_output->vbr_bitrate / 8) );
563 _mp3_header_output->frames = 0;
564 _mp3_header_output->time = 0;
virtual pos_type setCur(pos_type pos)=0
Set the value of the current position for reading.
virtual pos_type getCur()=0
Return the current position in the reader.
virtual size_type readChars(char_type buf[], size_type len)=0
Read up to len characters into buf and advance the internal position accordingly.
bool Parse(ID3_Reader &, size_t mp3size)
@ MP3FREQUENCIES_Reserved
@ MP3CHANNELMODE_DUAL_CHANNEL
@ MP3CHANNELMODE_SINGLE_CHANNEL
@ MP3CHANNELMODE_JOINT_STEREO
uint16 calcCRC(char *pFrame, size_t audiodatasize)
uint32 fto_nearest_i(float f)