00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MP3InternalsHuffman.hh"
00022
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027
00028
00029
00030 static unsigned const live_tabsel[2][3][16] = {
00031 { {32,32,64,96,128,160,192,224,256,288,320,352,384,416,448,448},
00032 {32,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,384},
00033 {32,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,320} },
00034
00035 { {32,32,48,56,64,80,96,112,128,144,160,176,192,224,256,256},
00036 {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160},
00037 {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160} }
00038 };
00039
00040
00041 static long const live_freqs[]
00042 = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 };
00043
00044 struct bandInfoStruct {
00045 int longIdx[23];
00046 int longDiff[22];
00047 int shortIdx[14];
00048 int shortDiff[13];
00049 };
00050
00051 static struct bandInfoStruct const bandInfo[7] = {
00052
00053 { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
00054 {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
00055 {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},
00056 {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
00057
00058 { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
00059 {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
00060 {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},
00061 {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
00062
00063 { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
00064 {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
00065 {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} ,
00066 {4,4,4,4,6,8,12,16,20,26,34,42,12} } ,
00067
00068
00069 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
00070 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
00071 {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} ,
00072 {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
00073
00074 { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
00075 {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
00076 {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} ,
00077 {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
00078
00079 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
00080 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
00081 {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},
00082 {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
00083
00084
00085 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
00086 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
00087 {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} ,
00088 {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
00089 };
00090
00091 unsigned int n_slen2[512];
00092 unsigned int i_slen2[256];
00093
00094 #define MPG_MD_MONO 3
00095
00096
00098
00099 MP3FrameParams::MP3FrameParams()
00100 : bv(frameBytes, 0, sizeof frameBytes) {
00101 oldHdr = firstHdr = 0;
00102
00103 static Boolean doneInit = False;
00104 if (doneInit) return;
00105
00106 int i,j,k,l;
00107
00108 for (i=0;i<5;i++) {
00109 for (j=0;j<6;j++) {
00110 for (k=0;k<6;k++) {
00111 int n = k + j * 6 + i * 36;
00112 i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
00113 }
00114 }
00115 }
00116 for (i=0;i<4;i++) {
00117 for (j=0;j<4;j++) {
00118 for (k=0;k<4;k++) {
00119 int n = k + j * 4 + i * 16;
00120 i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
00121 }
00122 }
00123 }
00124 for (i=0;i<4;i++) {
00125 for (j=0;j<3;j++) {
00126 int n = j + i * 3;
00127 i_slen2[n+244] = i|(j<<3) | (5<<12);
00128 n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
00129 }
00130 }
00131
00132 for (i=0;i<5;i++) {
00133 for (j=0;j<5;j++) {
00134 for (k=0;k<4;k++) {
00135 for (l=0;l<4;l++) {
00136 int n = l + k * 4 + j * 16 + i * 80;
00137 n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
00138 }
00139 }
00140 }
00141 }
00142 for (i=0;i<5;i++) {
00143 for (j=0;j<5;j++) {
00144 for (k=0;k<4;k++) {
00145 int n = k + j * 4 + i * 20;
00146 n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
00147 }
00148 }
00149 }
00150 doneInit = True;
00151 }
00152
00153 MP3FrameParams::~MP3FrameParams() {
00154 }
00155
00156 void MP3FrameParams::setParamsFromHeader() {
00157 if (hdr & (1<<20)) {
00158 isMPEG2 = (hdr & (1<<19)) ? 0x0 : 0x1;
00159 isMPEG2_5 = 0;
00160 }
00161 else {
00162 isMPEG2 = 1;
00163 isMPEG2_5 = 1;
00164 }
00165
00166 layer = 4-((hdr>>17)&3);
00167 if (layer == 4) layer = 3;
00168 bitrateIndex = ((hdr>>12)&0xf);
00169
00170 if (isMPEG2_5) {
00171 samplingFreqIndex = ((hdr>>10)&0x3) + 6;
00172 } else {
00173 samplingFreqIndex = ((hdr>>10)&0x3) + (isMPEG2*3);
00174 }
00175
00176 hasCRC = (hdr & 0x10000) == 0;
00177
00178 padding = ((hdr>>9)&0x1);
00179 extension = ((hdr>>8)&0x1);
00180 mode = ((hdr>>6)&0x3);
00181 mode_ext = ((hdr>>4)&0x3);
00182 copyright = ((hdr>>3)&0x1);
00183 original = ((hdr>>2)&0x1);
00184 emphasis = hdr & 0x3;
00185
00186 stereo = (mode == MPG_MD_MONO) ? 1 : 2;
00187
00188 if (((hdr>>10)&0x3) == 0x3) {
00189 #ifdef DEBUG_ERRORS
00190 fprintf(stderr,"Stream error - hdr: 0x%08x\n", hdr);
00191 #endif
00192 }
00193
00194 bitrate = live_tabsel[isMPEG2][layer-1][bitrateIndex];
00195 samplingFreq = live_freqs[samplingFreqIndex];
00196 isStereo = (stereo > 1);
00197 isFreeFormat = (bitrateIndex == 0);
00198 frameSize
00199 = ComputeFrameSize(bitrate, samplingFreq, padding, isMPEG2, layer);
00200 sideInfoSize = computeSideInfoSize();
00201 }
00202
00203 unsigned MP3FrameParams::computeSideInfoSize() {
00204 unsigned size;
00205
00206 if (isMPEG2) {
00207 size = isStereo ? 17 : 9;
00208 } else {
00209 size = isStereo ? 32 : 17;
00210 }
00211
00212 if (hasCRC) {
00213 size += 2;
00214 }
00215
00216 return size;
00217 }
00218
00219 unsigned ComputeFrameSize(unsigned bitrate, unsigned samplingFreq,
00220 Boolean usePadding, Boolean isMPEG2,
00221 unsigned char layer) {
00222 if (samplingFreq == 0) return 0;
00223 unsigned const bitrateMultiplier = (layer == 1) ? 12000*4 : 144000;
00224 unsigned framesize;
00225
00226 framesize = bitrate*bitrateMultiplier;
00227 framesize /= samplingFreq<<(isMPEG2 ? 1 : 0);
00228 framesize = framesize + usePadding - 4;
00229
00230 return framesize;
00231 }
00232
00233 #define TRUNC_FAIRLY
00234 static unsigned updateSideInfoSizes(MP3SideInfo& sideInfo, Boolean isMPEG2,
00235 unsigned char const* mainDataPtr,
00236 unsigned allowedNumBits,
00237 unsigned& part23Length0a,
00238 unsigned& part23Length0aTruncation,
00239 unsigned& part23Length0b,
00240 unsigned& part23Length0bTruncation,
00241 unsigned& part23Length1a,
00242 unsigned& part23Length1aTruncation,
00243 unsigned& part23Length1b,
00244 unsigned& part23Length1bTruncation) {
00245 unsigned p23L0, p23L1 = 0, p23L0Trunc = 0, p23L1Trunc = 0;
00246
00247 p23L0 = sideInfo.ch[0].gr[0].part2_3_length;
00248 p23L1 = isMPEG2 ? 0 : sideInfo.ch[0].gr[1].part2_3_length;
00249 #ifdef TRUNC_ONLY0
00250 if (p23L0 < allowedNumBits)
00251 allowedNumBits = p23L0;
00252 #endif
00253 #ifdef TRUNC_ONLY1
00254 if (p23L1 < allowedNumBits)
00255 allowedNumBits = p23L1;
00256 #endif
00257 if (p23L0 + p23L1 > allowedNumBits) {
00258
00259 unsigned truncation = p23L0 + p23L1 - allowedNumBits;
00260 #ifdef TRUNC_FAIRLY
00261 p23L0Trunc = (truncation*p23L0)/(p23L0 + p23L1);
00262 p23L1Trunc = truncation - p23L0Trunc;
00263 #endif
00264 #if defined(TRUNC_FAVOR0) || defined(TRUNC_ONLY0)
00265 p23L1Trunc = (truncation>p23L1) ? p23L1 : truncation;
00266 p23L0Trunc = truncation - p23L1Trunc;
00267 #endif
00268 #if defined(TRUNC_FAVOR1) || defined(TRUNC_ONLY1)
00269 p23L0Trunc = (truncation>p23L0) ? p23L0 : truncation;
00270 p23L1Trunc = truncation - p23L0Trunc;
00271 #endif
00272 }
00273
00274
00275 p23L0 -= p23L0Trunc; p23L1 -= p23L1Trunc;
00276 #ifdef DEBUG
00277 fprintf(stderr, "updateSideInfoSizes (allowed: %d): %d->%d, %d->%d\n", allowedNumBits, p23L0+p23L0Trunc, p23L0, p23L1+p23L1Trunc, p23L1);
00278 #endif
00279
00280
00281
00282
00283 updateSideInfoForHuffman(sideInfo, isMPEG2, mainDataPtr,
00284 p23L0, p23L1,
00285 part23Length0a, part23Length0aTruncation,
00286 part23Length0b, part23Length0bTruncation,
00287 part23Length1a, part23Length1aTruncation,
00288 part23Length1b, part23Length1bTruncation);
00289 p23L0 = part23Length0a + part23Length0b;
00290 p23L1 = part23Length1a + part23Length1b;
00291
00292 sideInfo.ch[0].gr[0].part2_3_length = p23L0;
00293 sideInfo.ch[0].gr[1].part2_3_length = p23L1;
00294 part23Length0bTruncation
00295 += sideInfo.ch[1].gr[0].part2_3_length;
00296 sideInfo.ch[1].gr[0].part2_3_length = 0;
00297 sideInfo.ch[1].gr[1].part2_3_length = 0;
00298
00299 return p23L0 + p23L1;
00300 }
00301
00302
00303 Boolean GetADUInfoFromMP3Frame(unsigned char const* framePtr,
00304 unsigned totFrameSize,
00305 unsigned& hdr, unsigned& frameSize,
00306 MP3SideInfo& sideInfo, unsigned& sideInfoSize,
00307 unsigned& backpointer, unsigned& aduSize) {
00308 if (totFrameSize < 4) return False;
00309
00310 MP3FrameParams fr;
00311 fr.hdr = ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
00312 | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
00313 fr.setParamsFromHeader();
00314 fr.setBytePointer(framePtr + 4, totFrameSize - 4);
00315
00316 frameSize = 4 + fr.frameSize;
00317
00318 if (fr.layer != 3) {
00319
00320 backpointer = 0;
00321 sideInfoSize = 0;
00322 aduSize = fr.frameSize;
00323 return True;
00324 }
00325
00326 sideInfoSize = fr.sideInfoSize;
00327 if (totFrameSize < 4 + sideInfoSize) return False;
00328
00329 fr.getSideInfo(sideInfo);
00330
00331 hdr = fr.hdr;
00332 backpointer = sideInfo.main_data_begin;
00333 unsigned numBits = sideInfo.ch[0].gr[0].part2_3_length;
00334 numBits += sideInfo.ch[0].gr[1].part2_3_length;
00335 numBits += sideInfo.ch[1].gr[0].part2_3_length;
00336 numBits += sideInfo.ch[1].gr[1].part2_3_length;
00337 aduSize = (numBits+7)/8;
00338 #ifdef DEBUG
00339 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);
00340 #endif
00341
00342 return True;
00343 }
00344
00345
00346 static void getSideInfo1(MP3FrameParams& fr, MP3SideInfo& si,
00347 int stereo, int ms_stereo, long sfreq,
00348 int ) {
00349 int ch, gr;
00350 #if 0
00351 int powdiff = (single == 3) ? 4 : 0;
00352 #endif
00353
00354
00355 si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
00356 si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
00357
00358 si.main_data_begin = fr.getBits(9);
00359 if (stereo == 1)
00360 si.private_bits = fr.getBits(5);
00361 else
00362 si.private_bits = fr.getBits(3);
00363
00364 for (ch=0; ch<stereo; ch++) {
00365 si.ch[ch].gr[0].scfsi = -1;
00366 si.ch[ch].gr[1].scfsi = fr.getBits(4);
00367 }
00368
00369 for (gr=0; gr<2; gr++) {
00370 for (ch=0; ch<stereo; ch++) {
00371 MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[gr];
00372
00373 gr_info.part2_3_length = fr.getBits(12);
00374 gr_info.big_values = fr.getBits(9);
00375 gr_info.global_gain = fr.getBits(8);
00376 #if 0
00377 gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
00378 if (ms_stereo) gr_info.pow2gain += 2;
00379 #endif
00380 gr_info.scalefac_compress = fr.getBits(4);
00381
00382 gr_info.window_switching_flag = fr.get1Bit();
00383 if (gr_info.window_switching_flag) {
00384 int i;
00385 gr_info.block_type = fr.getBits(2);
00386 gr_info.mixed_block_flag = fr.get1Bit();
00387 gr_info.table_select[0] = fr.getBits(5);
00388 gr_info.table_select[1] = fr.getBits(5);
00389
00390
00391
00392
00393 gr_info.table_select[2] = 0;
00394 for (i=0;i<3;i++) {
00395 gr_info.subblock_gain[i] = fr.getBits(3);
00396 gr_info.full_gain[i]
00397 = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
00398 }
00399
00400 #ifdef DEBUG_ERRORS
00401 if (gr_info.block_type == 0) {
00402 fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
00403 }
00404 #endif
00405
00406 gr_info.region1start = 36>>1;
00407 gr_info.region2start = 576>>1;
00408 }
00409 else
00410 {
00411 int i,r0c,r1c;
00412 for (i=0; i<3; i++) {
00413 gr_info.table_select[i] = fr.getBits(5);
00414 }
00415 r0c = gr_info.region0_count = fr.getBits(4);
00416 r1c = gr_info.region1_count = fr.getBits(3);
00417 gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
00418 gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
00419 gr_info.block_type = 0;
00420 gr_info.mixed_block_flag = 0;
00421 }
00422 gr_info.preflag = fr.get1Bit();
00423 gr_info.scalefac_scale = fr.get1Bit();
00424 gr_info.count1table_select = fr.get1Bit();
00425 }
00426 }
00427 }
00428
00429 static void getSideInfo2(MP3FrameParams& fr, MP3SideInfo& si,
00430 int stereo, int ms_stereo, long sfreq,
00431 int ) {
00432 int ch;
00433 #if 0
00434 int powdiff = (single == 3) ? 4 : 0;
00435 #endif
00436
00437
00438 si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
00439 si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
00440
00441 si.main_data_begin = fr.getBits(8);
00442 if (stereo == 1)
00443 si.private_bits = fr.get1Bit();
00444 else
00445 si.private_bits = fr.getBits(2);
00446
00447 for (ch=0; ch<stereo; ch++) {
00448 MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[0];
00449
00450 gr_info.part2_3_length = fr.getBits(12);
00451 si.ch[ch].gr[1].part2_3_length = 0;
00452
00453 gr_info.big_values = fr.getBits(9);
00454 gr_info.global_gain = fr.getBits(8);
00455 #if 0
00456 gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
00457 if (ms_stereo) gr_info.pow2gain += 2;
00458 #endif
00459 gr_info.scalefac_compress = fr.getBits(9);
00460
00461 gr_info.window_switching_flag = fr.get1Bit();
00462 if (gr_info.window_switching_flag) {
00463 int i;
00464 gr_info.block_type = fr.getBits(2);
00465 gr_info.mixed_block_flag = fr.get1Bit();
00466 gr_info.table_select[0] = fr.getBits(5);
00467 gr_info.table_select[1] = fr.getBits(5);
00468
00469
00470
00471
00472 gr_info.table_select[2] = 0;
00473 for (i=0;i<3;i++) {
00474 gr_info.subblock_gain[i] = fr.getBits(3);
00475 gr_info.full_gain[i]
00476 = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
00477 }
00478
00479 #ifdef DEBUG_ERRORS
00480 if (gr_info.block_type == 0) {
00481 fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
00482 }
00483 #endif
00484
00485
00486 if (gr_info.block_type == 2)
00487 gr_info.region1start = 36>>1;
00488 else {
00489 gr_info.region1start = 54>>1;
00490 }
00491 gr_info.region2start = 576>>1;
00492 }
00493 else
00494 {
00495 int i,r0c,r1c;
00496 for (i=0; i<3; i++) {
00497 gr_info.table_select[i] = fr.getBits(5);
00498 }
00499 r0c = gr_info.region0_count = fr.getBits(4);
00500 r1c = gr_info.region1_count = fr.getBits(3);
00501 gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
00502 gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
00503 gr_info.block_type = 0;
00504 gr_info.mixed_block_flag = 0;
00505 }
00506 gr_info.scalefac_scale = fr.get1Bit();
00507 gr_info.count1table_select = fr.get1Bit();
00508 }
00509 }
00510
00511
00512 #define MPG_MD_JOINT_STEREO 1
00513
00514 void MP3FrameParams::getSideInfo(MP3SideInfo& si) {
00515
00516 if (hasCRC) getBits(16);
00517
00518 int single = -1;
00519 int ms_stereo;
00520 int sfreq = samplingFreqIndex;
00521
00522 if (stereo == 1) {
00523 single = 0;
00524 }
00525
00526 ms_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x2);
00527
00528 if (isMPEG2) {
00529 getSideInfo2(*this, si, stereo, ms_stereo, sfreq, single);
00530 } else {
00531 getSideInfo1(*this, si, stereo, ms_stereo, sfreq, single);
00532 }
00533 }
00534
00535 static void putSideInfo1(BitVector& bv,
00536 MP3SideInfo const& si, Boolean isStereo) {
00537 int ch, gr, i;
00538 int stereo = isStereo ? 2 : 1;
00539
00540 bv.putBits(si.main_data_begin,9);
00541 if (stereo == 1)
00542 bv.putBits(si.private_bits, 5);
00543 else
00544 bv.putBits(si.private_bits, 3);
00545
00546 for (ch=0; ch<stereo; ch++) {
00547 bv.putBits(si.ch[ch].gr[1].scfsi, 4);
00548 }
00549
00550 for (gr=0; gr<2; gr++) {
00551 for (ch=0; ch<stereo; ch++) {
00552 MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[gr];
00553
00554 bv.putBits(gr_info.part2_3_length, 12);
00555 bv.putBits(gr_info.big_values, 9);
00556 bv.putBits(gr_info.global_gain, 8);
00557 bv.putBits(gr_info.scalefac_compress, 4);
00558 bv.put1Bit(gr_info.window_switching_flag);
00559 if (gr_info.window_switching_flag) {
00560 bv.putBits(gr_info.block_type, 2);
00561 bv.put1Bit(gr_info.mixed_block_flag);
00562 for (i=0; i<2; i++)
00563 bv.putBits(gr_info.table_select[i], 5);
00564 for (i=0; i<3; i++)
00565 bv.putBits(gr_info.subblock_gain[i], 3);
00566 }
00567 else {
00568 for (i=0; i<3; i++)
00569 bv.putBits(gr_info.table_select[i], 5);
00570 bv.putBits(gr_info.region0_count, 4);
00571 bv.putBits(gr_info.region1_count, 3);
00572 }
00573
00574 bv.put1Bit(gr_info.preflag);
00575 bv.put1Bit(gr_info.scalefac_scale);
00576 bv.put1Bit(gr_info.count1table_select);
00577 }
00578 }
00579 }
00580
00581 static void putSideInfo2(BitVector& bv,
00582 MP3SideInfo const& si, Boolean isStereo) {
00583 int ch, i;
00584 int stereo = isStereo ? 2 : 1;
00585
00586 bv.putBits(si.main_data_begin,8);
00587 if (stereo == 1)
00588 bv.put1Bit(si.private_bits);
00589 else
00590 bv.putBits(si.private_bits, 2);
00591
00592 for (ch=0; ch<stereo; ch++) {
00593 MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[0];
00594
00595 bv.putBits(gr_info.part2_3_length, 12);
00596 bv.putBits(gr_info.big_values, 9);
00597 bv.putBits(gr_info.global_gain, 8);
00598 bv.putBits(gr_info.scalefac_compress, 9);
00599 bv.put1Bit(gr_info.window_switching_flag);
00600 if (gr_info.window_switching_flag) {
00601 bv.putBits(gr_info.block_type, 2);
00602 bv.put1Bit(gr_info.mixed_block_flag);
00603 for (i=0; i<2; i++)
00604 bv.putBits(gr_info.table_select[i], 5);
00605 for (i=0; i<3; i++)
00606 bv.putBits(gr_info.subblock_gain[i], 3);
00607 }
00608 else {
00609 for (i=0; i<3; i++)
00610 bv.putBits(gr_info.table_select[i], 5);
00611 bv.putBits(gr_info.region0_count, 4);
00612 bv.putBits(gr_info.region1_count, 3);
00613 }
00614
00615 bv.put1Bit(gr_info.scalefac_scale);
00616 bv.put1Bit(gr_info.count1table_select);
00617 }
00618 }
00619
00620 static void PutMP3SideInfoIntoFrame(MP3SideInfo const& si,
00621 MP3FrameParams const& fr,
00622 unsigned char* framePtr) {
00623 if (fr.hasCRC) framePtr += 2;
00624
00625 BitVector bv(framePtr, 0, 8*fr.sideInfoSize);
00626
00627 if (fr.isMPEG2) {
00628 putSideInfo2(bv, si, fr.isStereo);
00629 } else {
00630 putSideInfo1(bv, si, fr.isStereo);
00631 }
00632 }
00633
00634
00635 Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,
00636 unsigned newBackpointer) {
00637 if (totFrameSize < 4) return False;
00638
00639 MP3FrameParams fr;
00640 fr.hdr = ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
00641 | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
00642 fr.setParamsFromHeader();
00643 fr.setBytePointer(framePtr + 4, totFrameSize - 4);
00644
00645 if (totFrameSize < 4 + fr.sideInfoSize) return False;
00646
00647 MP3SideInfo si;
00648 fr.getSideInfo(si);
00649
00650 si.main_data_begin = newBackpointer;
00651
00652 si.ch[0].gr[0].part2_3_length = si.ch[0].gr[0].big_values = 0;
00653 si.ch[1].gr[0].part2_3_length = si.ch[1].gr[0].big_values = 0;
00654 si.ch[0].gr[1].part2_3_length = si.ch[0].gr[1].big_values = 0;
00655 si.ch[1].gr[1].part2_3_length = si.ch[1].gr[1].big_values = 0;
00656
00657 PutMP3SideInfoIntoFrame(si, fr, framePtr + 4);
00658
00659 return True;
00660 }
00661
00662
00663 static unsigned MP3BitrateToBitrateIndex(unsigned bitrate ,
00664 Boolean isMPEG2) {
00665 for (unsigned i = 1; i < 15; ++i) {
00666 if (live_tabsel[isMPEG2][2][i] >= bitrate)
00667 return i;
00668 }
00669
00670
00671 return 14;
00672 }
00673
00674 static void outputHeader(unsigned char* toPtr, unsigned hdr) {
00675 toPtr[0] = (unsigned char)(hdr>>24);
00676 toPtr[1] = (unsigned char)(hdr>>16);
00677 toPtr[2] = (unsigned char)(hdr>>8);
00678 toPtr[3] = (unsigned char)(hdr);
00679 }
00680
00681 static void assignADUBackpointer(MP3FrameParams const& fr,
00682 unsigned aduSize,
00683 MP3SideInfo& sideInfo,
00684 unsigned& availableBytesForBackpointer) {
00685
00686 unsigned maxBackpointerSize = fr.isMPEG2 ? 255 : 511;
00687
00688 unsigned backpointerSize = availableBytesForBackpointer;
00689 if (backpointerSize > maxBackpointerSize) {
00690 backpointerSize = maxBackpointerSize;
00691 }
00692
00693
00694 sideInfo.main_data_begin = backpointerSize;
00695
00696
00697 availableBytesForBackpointer
00698 = backpointerSize + fr.frameSize - fr.sideInfoSize ;
00699 if (availableBytesForBackpointer < aduSize) {
00700 availableBytesForBackpointer = 0;
00701 } else {
00702 availableBytesForBackpointer -= aduSize;
00703 }
00704 }
00705
00706 unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,
00707 unsigned toBitrate,
00708 unsigned char* toPtr, unsigned toMaxSize,
00709 unsigned& availableBytesForBackpointer) {
00710
00711 unsigned hdr, inFrameSize, inSideInfoSize, backpointer, inAduSize;
00712 MP3SideInfo sideInfo;
00713 if (!GetADUInfoFromMP3Frame(fromPtr, fromSize,
00714 hdr, inFrameSize, sideInfo, inSideInfoSize,
00715 backpointer, inAduSize)) {
00716 return 0;
00717 }
00718 fromPtr += (4+inSideInfoSize);
00719
00720
00721
00722 Boolean isMPEG2 = ((hdr&0x00080000) == 0);
00723 unsigned toBitrateIndex = MP3BitrateToBitrateIndex(toBitrate, isMPEG2);
00724 hdr &=~ 0xF000; hdr |= (toBitrateIndex<<12);
00725 hdr |= 0x10200;
00726 hdr &=~ 0xC0; hdr |= 0xC0;
00727
00728
00729 MP3FrameParams outFr;
00730 outFr.hdr = hdr;
00731 outFr.setParamsFromHeader();
00732
00733
00734 unsigned inAveAduSize = inFrameSize - inSideInfoSize;
00735 unsigned outAveAduSize = outFr.frameSize - outFr.sideInfoSize;
00736 unsigned desiredOutAduSize
00737 = (2*inAduSize*outAveAduSize + inAveAduSize)/(2*inAveAduSize);
00738
00739
00740 if (toMaxSize < (4 + outFr.sideInfoSize)) return 0;
00741 unsigned maxOutAduSize = toMaxSize - (4 + outFr.sideInfoSize);
00742 if (desiredOutAduSize > maxOutAduSize) {
00743 desiredOutAduSize = maxOutAduSize;
00744 }
00745
00746
00747
00748 unsigned part23Length0a, part23Length0aTruncation;
00749 unsigned part23Length0b, part23Length0bTruncation;
00750 unsigned part23Length1a, part23Length1aTruncation;
00751 unsigned part23Length1b, part23Length1bTruncation;
00752 unsigned numAduBits
00753 = updateSideInfoSizes(sideInfo, outFr.isMPEG2,
00754 fromPtr, 8*desiredOutAduSize,
00755 part23Length0a, part23Length0aTruncation,
00756 part23Length0b, part23Length0bTruncation,
00757 part23Length1a, part23Length1aTruncation,
00758 part23Length1b, part23Length1bTruncation);
00759 #ifdef DEBUG
00760 fprintf(stderr, "shrinkage %d->%d [(%d,%d),(%d,%d)] (trunc: [(%d,%d),(%d,%d)]) {%d}\n", inAduSize, (numAduBits+7)/8,
00761 part23Length0a, part23Length0b, part23Length1a, part23Length1b,
00762 part23Length0aTruncation, part23Length0bTruncation,
00763 part23Length1aTruncation, part23Length1bTruncation,
00764 maxOutAduSize);
00765 #endif
00766 unsigned actualOutAduSize = (numAduBits+7)/8;
00767
00768
00769 assignADUBackpointer(outFr, actualOutAduSize, sideInfo, availableBytesForBackpointer);
00770
00772
00773
00774 outputHeader(toPtr, hdr); toPtr += 4;
00775
00776
00777 PutMP3SideInfoIntoFrame(sideInfo, outFr, toPtr); toPtr += outFr.sideInfoSize;
00778
00779
00780 unsigned toBitOffset = 0;
00781 unsigned fromBitOffset = 0;
00782
00783
00784 memmove(toPtr, fromPtr, (part23Length0a+7)/8);
00785 toBitOffset += part23Length0a;
00786 fromBitOffset += part23Length0a + part23Length0aTruncation;
00787
00788
00789 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length0b);
00790 toBitOffset += part23Length0b;
00791 fromBitOffset += part23Length0b + part23Length0bTruncation;
00792
00793
00794 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1a);
00795 toBitOffset += part23Length1a;
00796 fromBitOffset += part23Length1a + part23Length1aTruncation;
00797
00798
00799 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1b);
00800 toBitOffset += part23Length1b;
00801
00802
00803 unsigned char const zero = '\0';
00804 shiftBits(toPtr, toBitOffset, &zero, 0,
00805 actualOutAduSize*8 - numAduBits);
00806
00807 return 4 + outFr.sideInfoSize + actualOutAduSize;
00808 }