📄 mp3internals.cpp
字号:
} }}MP3FrameParams::~MP3FrameParams() {}void MP3FrameParams::setParamsFromHeader() { if (hdr & (1<<20)) { isMPEG2 = (hdr & (1<<19)) ? 0x0 : 0x1; isMPEG2_5 = 0; } else { isMPEG2 = 1; isMPEG2_5 = 1; } layer = 4-((hdr>>17)&3); if (layer == 4) layer = 3; // layer==4 is not allowed bitrateIndex = ((hdr>>12)&0xf); if (isMPEG2_5) { samplingFreqIndex = 6; } else { samplingFreqIndex = ((hdr>>10)&0x3) + (isMPEG2*3); } hasCRC = ((hdr>>16)&0x1)^0x1; padding = ((hdr>>9)&0x1); extension = ((hdr>>8)&0x1); mode = ((hdr>>6)&0x3); mode_ext = ((hdr>>4)&0x3); copyright = ((hdr>>3)&0x1); original = ((hdr>>2)&0x1); emphasis = hdr & 0x3; stereo = (mode == MPG_MD_MONO) ? 1 : 2; if (((hdr>>10)&0x3) == 0x3) {#ifdef DEBUG_ERRORS fprintf(stderr,"Stream error - hdr: 0x%08x\n", hdr);#endif } bitrate = tabsel_123[isMPEG2][layer-1][bitrateIndex]; samplingFreq = freqs[samplingFreqIndex]; isStereo = (stereo > 1); isFreeFormat = (bitrateIndex == 0); frameSize = ComputeFrameSize(bitrate, samplingFreq, padding, isMPEG2, layer); sideInfoSize = computeSideInfoSize(); }unsigned MP3FrameParams::computeSideInfoSize() { unsigned size; if (isMPEG2) { size = isStereo ? 17 : 9; } else { size = isStereo ? 32 : 17; } if (hasCRC) { size += 2; } return size;}unsigned ComputeFrameSize(unsigned bitrate, unsigned samplingFreq, Boolean usePadding, Boolean isMPEG2, unsigned char layer) { unsigned const bitrateMultiplier = (layer == 1) ? 12000*4 : 144000; unsigned framesize; framesize = bitrate*bitrateMultiplier; framesize /= samplingFreq<<isMPEG2; framesize = framesize + usePadding - 4; return framesize;}#if 0#define TRUNC_FAIRLYstatic unsigned updateSideInfoSizes(MP3SideInfo& sideInfo, Boolean isMPEG2, unsigned char const* mainDataPtr, unsigned allowedNumBits, unsigned& part23Length0a, unsigned& part23Length0aTruncation, unsigned& part23Length0b, unsigned& part23Length0bTruncation, unsigned& part23Length1a, unsigned& part23Length1aTruncation, unsigned& part23Length1b, unsigned& part23Length1bTruncation) { unsigned p23L0, p23L1 = 0, p23L0Trunc = 0, p23L1Trunc = 0; p23L0 = sideInfo.ch[0].gr[0].part2_3_length; p23L1 = isMPEG2 ? 0 : sideInfo.ch[0].gr[1].part2_3_length;#ifdef TRUNC_ONLY0 if (p23L0 < allowedNumBits) allowedNumBits = p23L0;#endif#ifdef TRUNC_ONLY1 if (p23L1 < allowedNumBits) allowedNumBits = p23L1;#endif if (p23L0 + p23L1 > allowedNumBits) { /* We need to shorten one or both fields */ unsigned truncation = p23L0 + p23L1 - allowedNumBits;#ifdef TRUNC_FAIRLY p23L0Trunc = (truncation*p23L0)/(p23L0 + p23L1); p23L1Trunc = truncation - p23L0Trunc;#endif#if defined(TRUNC_FAVOR0) || defined(TRUNC_ONLY0) p23L1Trunc = (truncation>p23L1) ? p23L1 : truncation; p23L0Trunc = truncation - p23L1Trunc;#endif#if defined(TRUNC_FAVOR1) || defined(TRUNC_ONLY1) p23L0Trunc = (truncation>p23L0) ? p23L0 : truncation; p23L1Trunc = truncation - p23L0Trunc;#endif } /* ASSERT: (p23L0Trunc <= p23L0) && (p23l1Trunc <= p23L1) */ p23L0 -= p23L0Trunc; p23L1 -= p23L1Trunc;#ifdef DEBUG fprintf(stderr, "updateSideInfoSizes (allowed: %d): %d->%d, %d->%d\n", allowedNumBits, p23L0+p23L0Trunc, p23L0, p23L1+p23L1Trunc, p23L1);#endif // The truncations computed above are still estimates. We need to // adjust them so that the new fields will continue to end on // Huffman-encoded sample boundaries: updateSideInfoForHuffman(sideInfo, isMPEG2, mainDataPtr, p23L0, p23L1, part23Length0a, part23Length0aTruncation, part23Length0b, part23Length0bTruncation, part23Length1a, part23Length1aTruncation, part23Length1b, part23Length1bTruncation); p23L0 = part23Length0a + part23Length0b; p23L1 = part23Length1a + part23Length1b; sideInfo.ch[0].gr[0].part2_3_length = p23L0; sideInfo.ch[0].gr[1].part2_3_length = p23L1; part23Length0bTruncation += sideInfo.ch[1].gr[0].part2_3_length; /* allow for stereo */ sideInfo.ch[1].gr[0].part2_3_length = 0; /* output mono */ sideInfo.ch[1].gr[1].part2_3_length = 0; /* output mono */ return p23L0 + p23L1;}#endifBoolean GetADUInfoFromMP3Frame(unsigned char const* framePtr, unsigned totFrameSize, unsigned& hdr, unsigned& frameSize, MP3SideInfo& sideInfo, unsigned& sideInfoSize, unsigned& backpointer, unsigned& aduSize) { if (totFrameSize < 4) return False; // there's not enough data MP3FrameParams fr; fr.hdr = ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16) | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3]; fr.setParamsFromHeader(); fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr frameSize = 4 + fr.frameSize; sideInfoSize = fr.sideInfoSize; if (totFrameSize < 4 + sideInfoSize) return False; // not enough data fr.getSideInfo(sideInfo); hdr = fr.hdr; backpointer = sideInfo.main_data_begin; unsigned numBits = sideInfo.ch[0].gr[0].part2_3_length; numBits += sideInfo.ch[0].gr[1].part2_3_length; numBits += sideInfo.ch[1].gr[0].part2_3_length; numBits += sideInfo.ch[1].gr[1].part2_3_length; aduSize = (numBits+7)/8;#ifdef DEBUG fprintf(stderr, "mp3GetADUInfoFromFrame: hdr: %08x, frameSize: %d, part2_3_lengths: %d,%d,%d,%d, aduSize: %d, backpointer: %d\n", hdr, frameSize, sideInfo.ch[0].gr[0].part2_3_length, sideInfo.ch[0].gr[1].part2_3_length, sideInfo.ch[1].gr[0].part2_3_length, sideInfo.ch[1].gr[1].part2_3_length, aduSize, backpointer);#endif return True;}static void getSideInfo1(MP3FrameParams& fr, MP3SideInfo& si, int stereo, int ms_stereo, long sfreq, int single) { int ch, gr; int powdiff = (single == 3) ? 4 : 0; /* initialize all four "part2_3_length" fields to zero: */ si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0; si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0; si.main_data_begin = fr.getBits(9); if (stereo == 1) si.private_bits = fr.getBits(5); else si.private_bits = fr.getBits(3); for (ch=0; ch<stereo; ch++) { si.ch[ch].gr[0].scfsi = -1; si.ch[ch].gr[1].scfsi = fr.getBits(4); } for (gr=0; gr<2; gr++) { for (ch=0; ch<stereo; ch++) { MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[gr]; gr_info.part2_3_length = fr.getBits(12); gr_info.big_values = fr.getBits(9); gr_info.global_gain = fr.getBits(8); gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff; if (ms_stereo) gr_info.pow2gain += 2; gr_info.scalefac_compress = fr.getBits(4);/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */ gr_info.window_switching_flag = fr.get1Bit(); if (gr_info.window_switching_flag) { int i; gr_info.block_type = fr.getBits(2); gr_info.mixed_block_flag = fr.get1Bit(); gr_info.table_select[0] = fr.getBits(5); gr_info.table_select[1] = fr.getBits(5); /* * table_select[2] not needed, because there is no region2, * but to satisfy some verifications tools we set it either. */ gr_info.table_select[2] = 0; for (i=0;i<3;i++) { gr_info.subblock_gain[i] = fr.getBits(3); gr_info.full_gain[i] = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3); }#ifdef DEBUG_ERRORS if (gr_info.block_type == 0) { fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n"); }#endif /* region_count/start parameters are implicit in this case. */ gr_info.region1start = 36>>1; gr_info.region2start = 576>>1; } else { int i,r0c,r1c; for (i=0; i<3; i++) { gr_info.table_select[i] = fr.getBits(5); } r0c = gr_info.region0_count = fr.getBits(4); r1c = gr_info.region1_count = fr.getBits(3); gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ; gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1; gr_info.block_type = 0; gr_info.mixed_block_flag = 0; } gr_info.preflag = fr.get1Bit(); gr_info.scalefac_scale = fr.get1Bit(); gr_info.count1table_select = fr.get1Bit(); } }}static void getSideInfo2(MP3FrameParams& fr, MP3SideInfo& si, int stereo, int ms_stereo, long sfreq, int single) { int ch; int powdiff = (single == 3) ? 4 : 0; /* initialize all four "part2_3_length" fields to zero: */ si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0; si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0; si.main_data_begin = fr.getBits(8); if (stereo == 1) si.private_bits = fr.get1Bit(); else si.private_bits = fr.getBits(2); for (ch=0; ch<stereo; ch++) { MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[0]; gr_info.part2_3_length = fr.getBits(12); si.ch[ch].gr[1].part2_3_length = 0; /* to ensure granule 1 unused */ gr_info.big_values = fr.getBits(9); gr_info.global_gain = fr.getBits(8); gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff; if (ms_stereo) gr_info.pow2gain += 2; gr_info.scalefac_compress = fr.getBits(9);/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */ gr_info.window_switching_flag = fr.get1Bit(); if (gr_info.window_switching_flag) { int i; gr_info.block_type = fr.getBits(2); gr_info.mixed_block_flag = fr.get1Bit(); gr_info.table_select[0] = fr.getBits(5); gr_info.table_select[1] = fr.getBits(5); /* * table_select[2] not needed, because there is no region2, * but to satisfy some verifications tools we set it either. */ gr_info.table_select[2] = 0; for (i=0;i<3;i++) { gr_info.subblock_gain[i] = fr.getBits(3); gr_info.full_gain[i] = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3); }#ifdef DEBUG_ERRORS if (gr_info.block_type == 0) { fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n"); }#endif /* region_count/start parameters are implicit in this case. */ /* check this again! */ if (gr_info.block_type == 2) gr_info.region1start = 36>>1; else { gr_info.region1start = 54>>1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -