⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3internals.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********This library is free software; you can redistribute it and/or modify it underthe terms of the GNU Lesser General Public License as published by theFree Software Foundation; either version 2.1 of the License, or (at youroption) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)This library is distributed in the hope that it will be useful, but WITHOUTANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License formore details.You should have received a copy of the GNU Lesser General Public Licensealong with this library; if not, write to the Free Software Foundation, Inc.,59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**********/// "liveMedia"// Copyright (c) 1996-2004 Live Networks, Inc.  All rights reserved.// MP3 internal implementation details// Implementation#include "MP3InternalsHuffman.hh"#include <stdlib.h>#include <math.h>#include <stdio.h>#include <string.h>// This is crufty old code that needs to be cleaned up #####static unsigned live_tabsel[2][3][16] = {   { {32,32,64,96,128,160,192,224,256,288,320,352,384,416,448,448},     {32,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,384},     {32,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,320} },   { {32,32,48,56,64,80,96,112,128,144,160,176,192,224,256,256},     {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160},     {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160} }};/* Note: live_tabsel[*][*][0 or 15] shouldn't occur; use dummy values there */static long live_freqs[]= { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 };struct bandInfoStruct {  int longIdx[23];  int longDiff[22];  int shortIdx[14];  int shortDiff[13];};static struct bandInfoStruct const bandInfo[7] = { /* MPEG 1.0 */ { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},   {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},   {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},   {4,4,4,4,6,8,10,12,14,18,22,30,56} } , { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},   {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},   {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},   {4,4,4,4,6,6,10,12,14,16,20,26,66} } , { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,   {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,   {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,   {4,4,4,4,6,8,12,16,20,26,34,42,12} }  ,/* MPEG 2.0 */ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,   {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,   {4,4,4,6,6,8,10,14,18,26,32,42,18 } } , { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},   {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,   {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,   {4,4,4,6,8,10,12,14,18,24,32,44,12 } } , { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },   {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},   {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,/* MPEG 2.5, wrong! table (it's just a copy of MPEG 2.0/44.1kHz) */ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,   {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,   {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,};unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */#define MPG_MD_MONO 3 ////////// MP3FrameParams //////////MP3FrameParams::MP3FrameParams()  : bv(frameBytes, 0, sizeof frameBytes) /* by default */ {  oldHdr = firstHdr = 0;  static Boolean doneInit = False;  if (doneInit) return;  doneInit = True;  int i,j,k,l;  for (i=0;i<5;i++) {    for (j=0;j<6;j++) {      for (k=0;k<6;k++) {        int n = k + j * 6 + i * 36;        i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);      }    }  }  for (i=0;i<4;i++) {    for (j=0;j<4;j++) {      for (k=0;k<4;k++) {        int n = k + j * 4 + i * 16;        i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);      }    }  }  for (i=0;i<4;i++) {    for (j=0;j<3;j++) {      int n = j + i * 3;      i_slen2[n+244] = i|(j<<3) | (5<<12);      n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);    }  }  for (i=0;i<5;i++) {    for (j=0;j<5;j++) {      for (k=0;k<4;k++) {        for (l=0;l<4;l++) {          int n = l + k * 4 + j * 16 + i * 80;          n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);        }      }    }  }  for (i=0;i<5;i++) {    for (j=0;j<5;j++) {      for (k=0;k<4;k++) {        int n = k + j * 4 + i * 20;        n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);      }    }  }}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 = ((hdr>>10)&0x3) + 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 = live_tabsel[isMPEG2][layer-1][bitrateIndex];  samplingFreq = live_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;}#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;}Boolean 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;  if (fr.layer != 3) {    // Special case for non-layer III frames    backpointer = 0;    sideInfoSize = 0;    aduSize = fr.frameSize;    return True;  }  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;#if 0   int powdiff = (single == 3) ? 4 : 0;#endif   /* 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);#if 0       gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;       if (ms_stereo) gr_info.pow2gain += 2;#endif       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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -