30#define FRAMES_FLAG 0x0001
31#define BYTES_FLAG 0x0002
32#define TOC_FLAG 0x0004
33#define SCALE_FLAG 0x0008
35static int ExtractI4(
unsigned char *buf)
68uint16
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;
228 _mp3_header_internal *_tmpheader;
230 const size_t HEADERSIZE = 4;
231 char buf[HEADERSIZE+1];
246 _mp3_header_output->
frames = 0;
247 _mp3_header_output->
time = 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)
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 const size_t CRCSIZE = 2;
428 int vbr_header_offest = beg + sideinfo_len;
433 if ((_mp3_header_output->
crc ==
MP3CRC_OK) && mp3size < sideinfo_len)
438 char audiodata[38 + 1];
446 reader.
readChars(audiodata, sideinfo_len);
447 audiodata[sideinfo_len] =
'\0';
449 crc16 =
calcCRC(audiodata, sideinfo_len);
455 crcstored = (uint16)io::readBENumber(reader, CRCSIZE);
459 if (crcstored == crc16)
467 const size_t VBR_HEADER_MIN_SIZE = 8;
468 const size_t VBR_HEADER_MAX_SIZE = 120;
470 if (mp3size >= vbr_header_offest + VBR_HEADER_MIN_SIZE)
472 char vbrheaderdata[VBR_HEADER_MAX_SIZE+1];
473 unsigned char *pvbrdata = (
unsigned char *)vbrheaderdata;
474 int vbr_filesize = 0;
481 beg = vbr_header_offest;
483 reader.
readChars(vbrheaderdata, VBR_HEADER_MIN_SIZE);
484 vbrheaderdata[VBR_HEADER_MIN_SIZE] =
'\0';
486 if (pvbrdata[0] ==
'X' &&
487 pvbrdata[1] ==
'i' &&
488 pvbrdata[2] ==
'n' &&
493 vbr_flags = ExtractI4(pvbrdata);
497 int vbr_header_size = VBR_HEADER_MIN_SIZE
503 if (mp3size >= vbr_header_offest + vbr_header_size)
505 reader.
readChars(&vbrheaderdata[VBR_HEADER_MIN_SIZE], vbr_header_size - VBR_HEADER_MIN_SIZE);
506 vbrheaderdata[vbr_header_size] =
'\0';
512 vbr_frames = ExtractI4(pvbrdata);
518 vbr_filesize = ExtractI4(pvbrdata);
533 vbr_scale = ExtractI4(pvbrdata);
539 _mp3_header_output->
vbr_bitrate = (((vbr_filesize!=0) ? vbr_filesize : mp3size) / vbr_frames) * _mp3_header_output->
frequency / 144;
551 _mp3_header_output->
frames = vbr_frames;
561 _mp3_header_output->
frames = 0;
562 _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)