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 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 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 doneInit = True;
00106
00107 int i,j,k,l;
00108
00109 for (i=0;i<5;i++) {
00110 for (j=0;j<6;j++) {
00111 for (k=0;k<6;k++) {
00112 int n = k + j * 6 + i * 36;
00113 i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
00114 }
00115 }
00116 }
00117 for (i=0;i<4;i++) {
00118 for (j=0;j<4;j++) {
00119 for (k=0;k<4;k++) {
00120 int n = k + j * 4 + i * 16;
00121 i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
00122 }
00123 }
00124 }
00125 for (i=0;i<4;i++) {
00126 for (j=0;j<3;j++) {
00127 int n = j + i * 3;
00128 i_slen2[n+244] = i|(j<<3) | (5<<12);
00129 n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
00130 }
00131 }
00132
00133 for (i=0;i<5;i++) {
00134 for (j=0;j<5;j++) {
00135 for (k=0;k<4;k++) {
00136 for (l=0;l<4;l++) {
00137 int n = l + k * 4 + j * 16 + i * 80;
00138 n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
00139 }
00140 }
00141 }
00142 }
00143 for (i=0;i<5;i++) {
00144 for (j=0;j<5;j++) {
00145 for (k=0;k<4;k++) {
00146 int n = k + j * 4 + i * 20;
00147 n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
00148 }
00149 }
00150 }
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>>16)&0x1)^0x1;
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;
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, i_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 i_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x1);
00528
00529 if (isMPEG2) {
00530 getSideInfo2(*this, si, stereo, ms_stereo, sfreq, single);
00531 } else {
00532 getSideInfo1(*this, si, stereo, ms_stereo, sfreq, single);
00533 }
00534 }
00535
00536 static void putSideInfo1(BitVector& bv,
00537 MP3SideInfo const& si, Boolean isStereo) {
00538 int ch, gr, i;
00539 int stereo = isStereo ? 2 : 1;
00540
00541 bv.putBits(si.main_data_begin,9);
00542 if (stereo == 1)
00543 bv.putBits(si.private_bits, 5);
00544 else
00545 bv.putBits(si.private_bits, 3);
00546
00547 for (ch=0; ch<stereo; ch++) {
00548 bv.putBits(si.ch[ch].gr[1].scfsi, 4);
00549 }
00550
00551 for (gr=0; gr<2; gr++) {
00552 for (ch=0; ch<stereo; ch++) {
00553 MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[gr];
00554
00555 bv.putBits(gr_info.part2_3_length, 12);
00556 bv.putBits(gr_info.big_values, 9);
00557 bv.putBits(gr_info.global_gain, 8);
00558 bv.putBits(gr_info.scalefac_compress, 4);
00559 bv.put1Bit(gr_info.window_switching_flag);
00560 if (gr_info.window_switching_flag) {
00561 bv.putBits(gr_info.block_type, 2);
00562 bv.put1Bit(gr_info.mixed_block_flag);
00563 for (i=0; i<2; i++)
00564 bv.putBits(gr_info.table_select[i], 5);
00565 for (i=0; i<3; i++)
00566 bv.putBits(gr_info.subblock_gain[i], 3);
00567 }
00568 else {
00569 for (i=0; i<3; i++)
00570 bv.putBits(gr_info.table_select[i], 5);
00571 bv.putBits(gr_info.region0_count, 4);
00572 bv.putBits(gr_info.region1_count, 3);
00573 }
00574
00575 bv.put1Bit(gr_info.preflag);
00576 bv.put1Bit(gr_info.scalefac_scale);
00577 bv.put1Bit(gr_info.count1table_select);
00578 }
00579 }
00580 }
00581
00582 static void putSideInfo2(BitVector& bv,
00583 MP3SideInfo const& si, Boolean isStereo) {
00584 int ch, i;
00585 int stereo = isStereo ? 2 : 1;
00586
00587 bv.putBits(si.main_data_begin,8);
00588 if (stereo == 1)
00589 bv.put1Bit(si.private_bits);
00590 else
00591 bv.putBits(si.private_bits, 2);
00592
00593 for (ch=0; ch<stereo; ch++) {
00594 MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[0];
00595
00596 bv.putBits(gr_info.part2_3_length, 12);
00597 bv.putBits(gr_info.big_values, 9);
00598 bv.putBits(gr_info.global_gain, 8);
00599 bv.putBits(gr_info.scalefac_compress, 9);
00600 bv.put1Bit(gr_info.window_switching_flag);
00601 if (gr_info.window_switching_flag) {
00602 bv.putBits(gr_info.block_type, 2);
00603 bv.put1Bit(gr_info.mixed_block_flag);
00604 for (i=0; i<2; i++)
00605 bv.putBits(gr_info.table_select[i], 5);
00606 for (i=0; i<3; i++)
00607 bv.putBits(gr_info.subblock_gain[i], 3);
00608 }
00609 else {
00610 for (i=0; i<3; i++)
00611 bv.putBits(gr_info.table_select[i], 5);
00612 bv.putBits(gr_info.region0_count, 4);
00613 bv.putBits(gr_info.region1_count, 3);
00614 }
00615
00616 bv.put1Bit(gr_info.scalefac_scale);
00617 bv.put1Bit(gr_info.count1table_select);
00618 }
00619 }
00620
00621 static void PutMP3SideInfoIntoFrame(MP3SideInfo const& si,
00622 MP3FrameParams const& fr,
00623 unsigned char* framePtr) {
00624 if (fr.hasCRC) framePtr += 2;
00625
00626 BitVector bv(framePtr, 0, 8*fr.sideInfoSize);
00627
00628 if (fr.isMPEG2) {
00629 putSideInfo2(bv, si, fr.isStereo);
00630 } else {
00631 putSideInfo1(bv, si, fr.isStereo);
00632 }
00633 }
00634
00635
00636 Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,
00637 unsigned newBackpointer) {
00638 if (totFrameSize < 4) return False;
00639
00640 MP3FrameParams fr;
00641 fr.hdr = ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
00642 | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
00643 fr.setParamsFromHeader();
00644 fr.setBytePointer(framePtr + 4, totFrameSize - 4);
00645
00646 if (totFrameSize < 4 + fr.sideInfoSize) return False;
00647
00648 MP3SideInfo si;
00649 fr.getSideInfo(si);
00650
00651 si.main_data_begin = newBackpointer;
00652
00653 si.ch[0].gr[0].part2_3_length = si.ch[0].gr[0].big_values = 0;
00654 si.ch[1].gr[0].part2_3_length = si.ch[1].gr[0].big_values = 0;
00655 si.ch[0].gr[1].part2_3_length = si.ch[0].gr[1].big_values = 0;
00656 si.ch[1].gr[1].part2_3_length = si.ch[1].gr[1].big_values = 0;
00657
00658 PutMP3SideInfoIntoFrame(si, fr, framePtr + 4);
00659
00660 return True;
00661 }
00662
00663
00664 static unsigned MP3BitrateToBitrateIndex(unsigned bitrate ,
00665 Boolean isMPEG2) {
00666 for (unsigned i = 1; i < 15; ++i) {
00667 if (live_tabsel[isMPEG2][2][i] >= bitrate)
00668 return i;
00669 }
00670
00671
00672 return 14;
00673 }
00674
00675 static void outputHeader(unsigned char* toPtr, unsigned hdr) {
00676 toPtr[0] = (unsigned char)(hdr>>24);
00677 toPtr[1] = (unsigned char)(hdr>>16);
00678 toPtr[2] = (unsigned char)(hdr>>8);
00679 toPtr[3] = (unsigned char)(hdr);
00680 }
00681
00682 static void assignADUBackpointer(MP3FrameParams const& fr,
00683 unsigned aduSize,
00684 MP3SideInfo& sideInfo,
00685 unsigned& availableBytesForBackpointer) {
00686
00687 unsigned maxBackpointerSize = fr.isMPEG2 ? 255 : 511;
00688
00689 unsigned backpointerSize = availableBytesForBackpointer;
00690 if (backpointerSize > maxBackpointerSize) {
00691 backpointerSize = maxBackpointerSize;
00692 }
00693
00694
00695 sideInfo.main_data_begin = backpointerSize;
00696
00697
00698 availableBytesForBackpointer
00699 = backpointerSize + fr.frameSize - fr.sideInfoSize ;
00700 if (availableBytesForBackpointer < aduSize) {
00701 availableBytesForBackpointer = 0;
00702 } else {
00703 availableBytesForBackpointer -= aduSize;
00704 }
00705 }
00706
00707 unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,
00708 unsigned toBitrate,
00709 unsigned char* toPtr, unsigned toMaxSize,
00710 unsigned& availableBytesForBackpointer) {
00711
00712 unsigned hdr, inFrameSize, inSideInfoSize, backpointer, inAduSize;
00713 MP3SideInfo sideInfo;
00714 if (!GetADUInfoFromMP3Frame(fromPtr, fromSize,
00715 hdr, inFrameSize, sideInfo, inSideInfoSize,
00716 backpointer, inAduSize)) {
00717 return 0;
00718 }
00719 fromPtr += (4+inSideInfoSize);
00720
00721
00722
00723 Boolean isMPEG2 = ((hdr&0x00080000) == 0);
00724 unsigned toBitrateIndex = MP3BitrateToBitrateIndex(toBitrate, isMPEG2);
00725 hdr &=~ 0xF000; hdr |= (toBitrateIndex<<12);
00726 hdr |= 0x10200;
00727 hdr &=~ 0xC0; hdr |= 0xC0;
00728
00729
00730 MP3FrameParams outFr;
00731 outFr.hdr = hdr;
00732 outFr.setParamsFromHeader();
00733
00734
00735 unsigned inAveAduSize = inFrameSize - inSideInfoSize;
00736 unsigned outAveAduSize = outFr.frameSize - outFr.sideInfoSize;
00737 unsigned desiredOutAduSize
00738 = (2*inAduSize*outAveAduSize + inAveAduSize)/(2*inAveAduSize);
00739
00740
00741 if (toMaxSize < (4 + outFr.sideInfoSize)) return 0;
00742 unsigned maxOutAduSize = toMaxSize - (4 + outFr.sideInfoSize);
00743 if (desiredOutAduSize > maxOutAduSize) {
00744 desiredOutAduSize = maxOutAduSize;
00745 }
00746
00747
00748
00749 unsigned part23Length0a, part23Length0aTruncation;
00750 unsigned part23Length0b, part23Length0bTruncation;
00751 unsigned part23Length1a, part23Length1aTruncation;
00752 unsigned part23Length1b, part23Length1bTruncation;
00753 unsigned numAduBits
00754 = updateSideInfoSizes(sideInfo, outFr.isMPEG2,
00755 fromPtr, 8*desiredOutAduSize,
00756 part23Length0a, part23Length0aTruncation,
00757 part23Length0b, part23Length0bTruncation,
00758 part23Length1a, part23Length1aTruncation,
00759 part23Length1b, part23Length1bTruncation);
00760 #ifdef DEBUG
00761 fprintf(stderr, "shrinkage %d->%d [(%d,%d),(%d,%d)] (trunc: [(%d,%d),(%d,%d)]) {%d}\n", inAduSize, (numAduBits+7)/8,
00762 part23Length0a, part23Length0b, part23Length1a, part23Length1b,
00763 part23Length0aTruncation, part23Length0bTruncation,
00764 part23Length1aTruncation, part23Length1bTruncation,
00765 maxOutAduSize);
00766 #endif
00767 unsigned actualOutAduSize = (numAduBits+7)/8;
00768
00769
00770 assignADUBackpointer(outFr, actualOutAduSize, sideInfo, availableBytesForBackpointer);
00771
00773
00774
00775 outputHeader(toPtr, hdr); toPtr += 4;
00776
00777
00778 PutMP3SideInfoIntoFrame(sideInfo, outFr, toPtr); toPtr += outFr.sideInfoSize;
00779
00780
00781 unsigned toBitOffset = 0;
00782 unsigned fromBitOffset = 0;
00783
00784
00785 memmove(toPtr, fromPtr, (part23Length0a+7)/8);
00786 toBitOffset += part23Length0a;
00787 fromBitOffset += part23Length0a + part23Length0aTruncation;
00788
00789
00790 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length0b);
00791 toBitOffset += part23Length0b;
00792 fromBitOffset += part23Length0b + part23Length0bTruncation;
00793
00794
00795 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1a);
00796 toBitOffset += part23Length1a;
00797 fromBitOffset += part23Length1a + part23Length1aTruncation;
00798
00799
00800 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1b);
00801 toBitOffset += part23Length1b;
00802
00803
00804 unsigned char const zero = '\0';
00805 shiftBits(toPtr, toBitOffset, &zero, 0,
00806 actualOutAduSize*8 - numAduBits);
00807
00808 return 4 + outFr.sideInfoSize + actualOutAduSize;
00809 }