1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// MP3 internal implementation details
19// Implementation
20
21#include "MP3InternalsHuffman.hh"
22
23#include <stdlib.h>
24#include <math.h>
25#include <stdio.h>
26#include <string.h>
27
28// This is crufty old code that needs to be cleaned up #####
29
30static unsigned const live_tabsel[2][3][16] = {
31 { {32,32,64,96,128,160,192,224,256,288,320,352,384,416,448,448},
32 {32,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,384},
33 {32,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,320} },
34
35 { {32,32,48,56,64,80,96,112,128,144,160,176,192,224,256,256},
36 {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160},
37 {8,8,16,24,32,40,48,56,64,80,96,112,128,144,160,160} }
38};
39/* Note: live_tabsel[*][*][0 or 15] shouldn't occur; use dummy values there */
40
41static long const live_freqs[]
42= { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 };
43
44struct bandInfoStruct {
45 int longIdx[23];
46 int longDiff[22];
47 int shortIdx[14];
48 int shortDiff[13];
49};
50
51static struct bandInfoStruct const bandInfo[7] = {
52/* MPEG 1.0 */
53 { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
54 {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
55 {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},
56 {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
57
58 { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
59 {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
60 {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},
61 {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
62
63 { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
64 {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
65 {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} ,
66 {4,4,4,4,6,8,12,16,20,26,34,42,12} } ,
67
68/* MPEG 2.0 */
69 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
70 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
71 {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} ,
72 {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
73
74 { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
75 {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
76 {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} ,
77 {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
78
79 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
80 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
81 {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},
82 {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
83
84/* MPEG 2.5, wrong! table (it's just a copy of MPEG 2.0/44.1kHz) */
85 { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
86 {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
87 {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} ,
88 {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
89};
90
91unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
92unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
93
94#define MPG_MD_MONO 3
95
96
97////////// MP3FrameParams //////////
98
99MP3FrameParams::MP3FrameParams()
100 : bv(frameBytes, 0, sizeof frameBytes) /* by default */ {
101 oldHdr = firstHdr = 0;
102
103 static Boolean doneInit = False;
104 if (doneInit) return;
105
106 int i,j,k,l;
107
108 for (i=0;i<5;i++) {
109 for (j=0;j<6;j++) {
110 for (k=0;k<6;k++) {
111 int n = k + j * 6 + i * 36;
112 i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
113 }
114 }
115 }
116 for (i=0;i<4;i++) {
117 for (j=0;j<4;j++) {
118 for (k=0;k<4;k++) {
119 int n = k + j * 4 + i * 16;
120 i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
121 }
122 }
123 }
124 for (i=0;i<4;i++) {
125 for (j=0;j<3;j++) {
126 int n = j + i * 3;
127 i_slen2[n+244] = i|(j<<3) | (5<<12);
128 n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
129 }
130 }
131
132 for (i=0;i<5;i++) {
133 for (j=0;j<5;j++) {
134 for (k=0;k<4;k++) {
135 for (l=0;l<4;l++) {
136 int n = l + k * 4 + j * 16 + i * 80;
137 n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
138 }
139 }
140 }
141 }
142 for (i=0;i<5;i++) {
143 for (j=0;j<5;j++) {
144 for (k=0;k<4;k++) {
145 int n = k + j * 4 + i * 20;
146 n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
147 }
148 }
149 }
150 doneInit = True;
151}
152
153MP3FrameParams::~MP3FrameParams() {
154}
155
156void MP3FrameParams::setParamsFromHeader() {
157 if (hdr & (1<<20)) {
158 isMPEG2 = (hdr & (1<<19)) ? 0x0 : 0x1;
159 isMPEG2_5 = 0;
160 }
161 else {
162 isMPEG2 = 1;
163 isMPEG2_5 = 1;
164 }
165
166 layer = 4-((hdr>>17)&3);
167 if (layer == 4) layer = 3; // layer==4 is not allowed
168 bitrateIndex = ((hdr>>12)&0xf);
169
170 if (isMPEG2_5) {
171 samplingFreqIndex = ((hdr>>10)&0x3) + 6;
172 } else {
173 samplingFreqIndex = ((hdr>>10)&0x3) + (isMPEG2*3);
174 }
175
176 hasCRC = (hdr & 0x10000) == 0;
177
178 padding = ((hdr>>9)&0x1);
179 extension = ((hdr>>8)&0x1);
180 mode = ((hdr>>6)&0x3);
181 mode_ext = ((hdr>>4)&0x3);
182 copyright = ((hdr>>3)&0x1);
183 original = ((hdr>>2)&0x1);
184 emphasis = hdr & 0x3;
185
186 stereo = (mode == MPG_MD_MONO) ? 1 : 2;
187
188 if (((hdr>>10)&0x3) == 0x3) {
189#ifdef DEBUG_ERRORS
190 fprintf(stderr,"Stream error - hdr: 0x%08x\n", hdr);
191#endif
192 }
193
194 bitrate = live_tabsel[isMPEG2][layer-1][bitrateIndex];
195 samplingFreq = live_freqs[samplingFreqIndex];
196 isStereo = (stereo > 1);
197 isFreeFormat = (bitrateIndex == 0);
198 frameSize
199 = ComputeFrameSize(bitrate, samplingFreq, padding, isMPEG2, layer);
200 sideInfoSize = computeSideInfoSize();
201 }
202
203unsigned MP3FrameParams::computeSideInfoSize() {
204 unsigned size;
205
206 if (isMPEG2) {
207 size = isStereo ? 17 : 9;
208 } else {
209 size = isStereo ? 32 : 17;
210 }
211
212 if (hasCRC) {
213 size += 2;
214 }
215
216 return size;
217}
218
219unsigned ComputeFrameSize(unsigned bitrate, unsigned samplingFreq,
220 Boolean usePadding, Boolean isMPEG2,
221 unsigned char layer) {
222 if (samplingFreq == 0) return 0;
223 unsigned const bitrateMultiplier = (layer == 1) ? 12000*4 : 144000;
224 unsigned framesize;
225
226 framesize = bitrate*bitrateMultiplier;
227 framesize /= samplingFreq<<(isMPEG2 ? 1 : 0);
228 framesize = framesize + usePadding - 4;
229
230 return framesize;
231}
232
233#define TRUNC_FAIRLY
234static unsigned updateSideInfoSizes(MP3SideInfo& sideInfo, Boolean isMPEG2,
235 unsigned char const* mainDataPtr,
236 unsigned allowedNumBits,
237 unsigned& part23Length0a,
238 unsigned& part23Length0aTruncation,
239 unsigned& part23Length0b,
240 unsigned& part23Length0bTruncation,
241 unsigned& part23Length1a,
242 unsigned& part23Length1aTruncation,
243 unsigned& part23Length1b,
244 unsigned& part23Length1bTruncation) {
245 unsigned p23L0, p23L1 = 0, p23L0Trunc = 0, p23L1Trunc = 0;
246
247 p23L0 = sideInfo.ch[0].gr[0].part2_3_length;
248 p23L1 = isMPEG2 ? 0 : sideInfo.ch[0].gr[1].part2_3_length;
249#ifdef TRUNC_ONLY0
250 if (p23L0 < allowedNumBits)
251 allowedNumBits = p23L0;
252#endif
253#ifdef TRUNC_ONLY1
254 if (p23L1 < allowedNumBits)
255 allowedNumBits = p23L1;
256#endif
257 if (p23L0 + p23L1 > allowedNumBits) {
258 /* We need to shorten one or both fields */
259 unsigned truncation = p23L0 + p23L1 - allowedNumBits;
260#ifdef TRUNC_FAIRLY
261 p23L0Trunc = (truncation*p23L0)/(p23L0 + p23L1);
262 p23L1Trunc = truncation - p23L0Trunc;
263#endif
264#if defined(TRUNC_FAVOR0) || defined(TRUNC_ONLY0)
265 p23L1Trunc = (truncation>p23L1) ? p23L1 : truncation;
266 p23L0Trunc = truncation - p23L1Trunc;
267#endif
268#if defined(TRUNC_FAVOR1) || defined(TRUNC_ONLY1)
269 p23L0Trunc = (truncation>p23L0) ? p23L0 : truncation;
270 p23L1Trunc = truncation - p23L0Trunc;
271#endif
272 }
273
274 /* ASSERT: (p23L0Trunc <= p23L0) && (p23l1Trunc <= p23L1) */
275 p23L0 -= p23L0Trunc; p23L1 -= p23L1Trunc;
276#ifdef DEBUG
277 fprintf(stderr, "updateSideInfoSizes (allowed: %d): %d->%d, %d->%d\n", allowedNumBits, p23L0+p23L0Trunc, p23L0, p23L1+p23L1Trunc, p23L1);
278#endif
279
280 // The truncations computed above are still estimates. We need to
281 // adjust them so that the new fields will continue to end on
282 // Huffman-encoded sample boundaries:
283 updateSideInfoForHuffman(sideInfo, isMPEG2, mainDataPtr,
284 p23L0, p23L1,
285 part23Length0a, part23Length0aTruncation,
286 part23Length0b, part23Length0bTruncation,
287 part23Length1a, part23Length1aTruncation,
288 part23Length1b, part23Length1bTruncation);
289 p23L0 = part23Length0a + part23Length0b;
290 p23L1 = part23Length1a + part23Length1b;
291
292 sideInfo.ch[0].gr[0].part2_3_length = p23L0;
293 sideInfo.ch[0].gr[1].part2_3_length = p23L1;
294 part23Length0bTruncation
295 += sideInfo.ch[1].gr[0].part2_3_length; /* allow for stereo */
296 sideInfo.ch[1].gr[0].part2_3_length = 0; /* output mono */
297 sideInfo.ch[1].gr[1].part2_3_length = 0; /* output mono */
298
299 return p23L0 + p23L1;
300}
301
302
303Boolean GetADUInfoFromMP3Frame(unsigned char const* framePtr,
304 unsigned totFrameSize,
305 unsigned& hdr, unsigned& frameSize,
306 MP3SideInfo& sideInfo, unsigned& sideInfoSize,
307 unsigned& backpointer, unsigned& aduSize) {
308 if (totFrameSize < 4) return False; // there's not enough data
309
310 MP3FrameParams fr;
311 fr.hdr = ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
312 | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
313 fr.setParamsFromHeader();
314 fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr
315
316 frameSize = 4 + fr.frameSize;
317
318 if (fr.layer != 3) {
319 // Special case for non-layer III frames
320 backpointer = 0;
321 sideInfoSize = 0;
322 aduSize = fr.frameSize;
323 return True;
324 }
325
326 sideInfoSize = fr.sideInfoSize;
327 if (totFrameSize < 4 + sideInfoSize) return False; // not enough data
328
329 fr.getSideInfo(sideInfo);
330
331 hdr = fr.hdr;
332 backpointer = sideInfo.main_data_begin;
333 unsigned numBits = sideInfo.ch[0].gr[0].part2_3_length;
334 numBits += sideInfo.ch[0].gr[1].part2_3_length;
335 numBits += sideInfo.ch[1].gr[0].part2_3_length;
336 numBits += sideInfo.ch[1].gr[1].part2_3_length;
337 aduSize = (numBits+7)/8;
338#ifdef DEBUG
339 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);
340#endif
341
342 return True;
343}
344
345
346static void getSideInfo1(MP3FrameParams& fr, MP3SideInfo& si,
347 int stereo, int ms_stereo, long sfreq,
348 int /*single*/) {
349 int ch, gr;
350#if 0
351 int powdiff = (single == 3) ? 4 : 0;
352#endif
353
354 /* initialize all four "part2_3_length" fields to zero: */
355 si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
356 si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
357
358 si.main_data_begin = fr.getBits(9);
359 if (stereo == 1)
360 si.private_bits = fr.getBits(5);
361 else
362 si.private_bits = fr.getBits(3);
363
364 for (ch=0; ch<stereo; ch++) {
365 si.ch[ch].gr[0].scfsi = -1;
366 si.ch[ch].gr[1].scfsi = fr.getBits(4);
367 }
368
369 for (gr=0; gr<2; gr++) {
370 for (ch=0; ch<stereo; ch++) {
371 MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[gr];
372
373 gr_info.part2_3_length = fr.getBits(12);
374 gr_info.big_values = fr.getBits(9);
375 gr_info.global_gain = fr.getBits(8);
376#if 0
377 gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
378 if (ms_stereo) gr_info.pow2gain += 2;
379#endif
380 gr_info.scalefac_compress = fr.getBits(4);
381/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
382 gr_info.window_switching_flag = fr.get1Bit();
383 if (gr_info.window_switching_flag) {
384 int i;
385 gr_info.block_type = fr.getBits(2);
386 gr_info.mixed_block_flag = fr.get1Bit();
387 gr_info.table_select[0] = fr.getBits(5);
388 gr_info.table_select[1] = fr.getBits(5);
389 /*
390 * table_select[2] not needed, because there is no region2,
391 * but to satisfy some verifications tools we set it either.
392 */
393 gr_info.table_select[2] = 0;
394 for (i=0;i<3;i++) {
395 gr_info.subblock_gain[i] = fr.getBits(3);
396 gr_info.full_gain[i]
397 = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
398 }
399
400#ifdef DEBUG_ERRORS
401 if (gr_info.block_type == 0) {
402 fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
403 }
404#endif
405 /* region_count/start parameters are implicit in this case. */
406 gr_info.region1start = 36>>1;
407 gr_info.region2start = 576>>1;
408 }
409 else
410 {
411 int i,r0c,r1c;
412 for (i=0; i<3; i++) {
413 gr_info.table_select[i] = fr.getBits(5);
414 }
415 r0c = gr_info.region0_count = fr.getBits(4);
416 r1c = gr_info.region1_count = fr.getBits(3);
417 gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
418 gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
419 gr_info.block_type = 0;
420 gr_info.mixed_block_flag = 0;
421 }
422 gr_info.preflag = fr.get1Bit();
423 gr_info.scalefac_scale = fr.get1Bit();
424 gr_info.count1table_select = fr.get1Bit();
425 }
426 }
427}
428
429static void getSideInfo2(MP3FrameParams& fr, MP3SideInfo& si,
430 int stereo, int ms_stereo, long sfreq,
431 int /*single*/) {
432 int ch;
433#if 0
434 int powdiff = (single == 3) ? 4 : 0;
435#endif
436
437 /* initialize all four "part2_3_length" fields to zero: */
438 si.ch[0].gr[0].part2_3_length = 0; si.ch[1].gr[0].part2_3_length = 0;
439 si.ch[0].gr[1].part2_3_length = 0; si.ch[1].gr[1].part2_3_length = 0;
440
441 si.main_data_begin = fr.getBits(8);
442 if (stereo == 1)
443 si.private_bits = fr.get1Bit();
444 else
445 si.private_bits = fr.getBits(2);
446
447 for (ch=0; ch<stereo; ch++) {
448 MP3SideInfo::gr_info_s_t& gr_info = si.ch[ch].gr[0];
449
450 gr_info.part2_3_length = fr.getBits(12);
451 si.ch[ch].gr[1].part2_3_length = 0; /* to ensure granule 1 unused */
452
453 gr_info.big_values = fr.getBits(9);
454 gr_info.global_gain = fr.getBits(8);
455#if 0
456 gr_info.pow2gain = gainpow2+256 - gr_info.global_gain + powdiff;
457 if (ms_stereo) gr_info.pow2gain += 2;
458#endif
459 gr_info.scalefac_compress = fr.getBits(9);
460/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
461 gr_info.window_switching_flag = fr.get1Bit();
462 if (gr_info.window_switching_flag) {
463 int i;
464 gr_info.block_type = fr.getBits(2);
465 gr_info.mixed_block_flag = fr.get1Bit();
466 gr_info.table_select[0] = fr.getBits(5);
467 gr_info.table_select[1] = fr.getBits(5);
468 /*
469 * table_select[2] not needed, because there is no region2,
470 * but to satisfy some verifications tools we set it either.
471 */
472 gr_info.table_select[2] = 0;
473 for (i=0;i<3;i++) {
474 gr_info.subblock_gain[i] = fr.getBits(3);
475 gr_info.full_gain[i]
476 = gr_info.pow2gain + ((gr_info.subblock_gain[i])<<3);
477 }
478
479#ifdef DEBUG_ERRORS
480 if (gr_info.block_type == 0) {
481 fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
482 }
483#endif
484 /* region_count/start parameters are implicit in this case. */
485/* check this again! */
486 if (gr_info.block_type == 2)
487 gr_info.region1start = 36>>1;
488 else {
489 gr_info.region1start = 54>>1;
490 }
491 gr_info.region2start = 576>>1;
492 }
493 else
494 {
495 int i,r0c,r1c;
496 for (i=0; i<3; i++) {
497 gr_info.table_select[i] = fr.getBits(5);
498 }
499 r0c = gr_info.region0_count = fr.getBits(4);
500 r1c = gr_info.region1_count = fr.getBits(3);
501 gr_info.region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
502 gr_info.region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
503 gr_info.block_type = 0;
504 gr_info.mixed_block_flag = 0;
505 }
506 gr_info.scalefac_scale = fr.get1Bit();
507 gr_info.count1table_select = fr.get1Bit();
508 }
509}
510
511
512#define MPG_MD_JOINT_STEREO 1
513
514void MP3FrameParams::getSideInfo(MP3SideInfo& si) {
515 // First skip over the CRC if present:
516 if (hasCRC) getBits(16);
517
518 int single = -1;
519 int ms_stereo;
520 int sfreq = samplingFreqIndex;
521
522 if (stereo == 1) {
523 single = 0;
524 }
525
526 ms_stereo = (mode == MPG_MD_JOINT_STEREO) && (mode_ext & 0x2);
527
528 if (isMPEG2) {
529 getSideInfo2(*this, si, stereo, ms_stereo, sfreq, single);
530 } else {
531 getSideInfo1(*this, si, stereo, ms_stereo, sfreq, single);
532 }
533}
534
535static void putSideInfo1(BitVector& bv,
536 MP3SideInfo const& si, Boolean isStereo) {
537 int ch, gr, i;
538 int stereo = isStereo ? 2 : 1;
539
540 bv.putBits(si.main_data_begin,9);
541 if (stereo == 1)
542 bv.putBits(si.private_bits, 5);
543 else
544 bv.putBits(si.private_bits, 3);
545
546 for (ch=0; ch<stereo; ch++) {
547 bv.putBits(si.ch[ch].gr[1].scfsi, 4);
548 }
549
550 for (gr=0; gr<2; gr++) {
551 for (ch=0; ch<stereo; ch++) {
552 MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[gr];
553
554 bv.putBits(gr_info.part2_3_length, 12);
555 bv.putBits(gr_info.big_values, 9);
556 bv.putBits(gr_info.global_gain, 8);
557 bv.putBits(gr_info.scalefac_compress, 4);
558 bv.put1Bit(gr_info.window_switching_flag);
559 if (gr_info.window_switching_flag) {
560 bv.putBits(gr_info.block_type, 2);
561 bv.put1Bit(gr_info.mixed_block_flag);
562 for (i=0; i<2; i++)
563 bv.putBits(gr_info.table_select[i], 5);
564 for (i=0; i<3; i++)
565 bv.putBits(gr_info.subblock_gain[i], 3);
566 }
567 else {
568 for (i=0; i<3; i++)
569 bv.putBits(gr_info.table_select[i], 5);
570 bv.putBits(gr_info.region0_count, 4);
571 bv.putBits(gr_info.region1_count, 3);
572 }
573
574 bv.put1Bit(gr_info.preflag);
575 bv.put1Bit(gr_info.scalefac_scale);
576 bv.put1Bit(gr_info.count1table_select);
577 }
578 }
579}
580
581static void putSideInfo2(BitVector& bv,
582 MP3SideInfo const& si, Boolean isStereo) {
583 int ch, i;
584 int stereo = isStereo ? 2 : 1;
585
586 bv.putBits(si.main_data_begin,8);
587 if (stereo == 1)
588 bv.put1Bit(si.private_bits);
589 else
590 bv.putBits(si.private_bits, 2);
591
592 for (ch=0; ch<stereo; ch++) {
593 MP3SideInfo::gr_info_s_t const& gr_info = si.ch[ch].gr[0];
594
595 bv.putBits(gr_info.part2_3_length, 12);
596 bv.putBits(gr_info.big_values, 9);
597 bv.putBits(gr_info.global_gain, 8);
598 bv.putBits(gr_info.scalefac_compress, 9);
599 bv.put1Bit(gr_info.window_switching_flag);
600 if (gr_info.window_switching_flag) {
601 bv.putBits(gr_info.block_type, 2);
602 bv.put1Bit(gr_info.mixed_block_flag);
603 for (i=0; i<2; i++)
604 bv.putBits(gr_info.table_select[i], 5);
605 for (i=0; i<3; i++)
606 bv.putBits(gr_info.subblock_gain[i], 3);
607 }
608 else {
609 for (i=0; i<3; i++)
610 bv.putBits(gr_info.table_select[i], 5);
611 bv.putBits(gr_info.region0_count, 4);
612 bv.putBits(gr_info.region1_count, 3);
613 }
614
615 bv.put1Bit(gr_info.scalefac_scale);
616 bv.put1Bit(gr_info.count1table_select);
617 }
618}
619
620static void PutMP3SideInfoIntoFrame(MP3SideInfo const& si,
621 MP3FrameParams const& fr,
622 unsigned char* framePtr) {
623 if (fr.hasCRC) framePtr += 2; // skip CRC
624
625 BitVector bv(framePtr, 0, 8*fr.sideInfoSize);
626
627 if (fr.isMPEG2) {
628 putSideInfo2(bv, si, fr.isStereo);
629 } else {
630 putSideInfo1(bv, si, fr.isStereo);
631 }
632}
633
634
635Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,
636 unsigned newBackpointer) {
637 if (totFrameSize < 4) return False; // there's not enough data
638
639 MP3FrameParams fr;
640 fr.hdr = ((unsigned)framePtr[0] << 24) | ((unsigned)framePtr[1] << 16)
641 | ((unsigned)framePtr[2] << 8) | (unsigned)framePtr[3];
642 fr.setParamsFromHeader();
643 fr.setBytePointer(framePtr + 4, totFrameSize - 4); // skip hdr
644
645 if (totFrameSize < 4 + fr.sideInfoSize) return False; // not enough data
646
647 MP3SideInfo si;
648 fr.getSideInfo(si);
649
650 si.main_data_begin = newBackpointer; /* backpointer */
651 /* set all four "part2_3_length" and "big_values" fields to zero: */
652 si.ch[0].gr[0].part2_3_length = si.ch[0].gr[0].big_values = 0;
653 si.ch[1].gr[0].part2_3_length = si.ch[1].gr[0].big_values = 0;
654 si.ch[0].gr[1].part2_3_length = si.ch[0].gr[1].big_values = 0;
655 si.ch[1].gr[1].part2_3_length = si.ch[1].gr[1].big_values = 0;
656
657 PutMP3SideInfoIntoFrame(si, fr, framePtr + 4);
658
659 return True;
660}
661
662
663static unsigned MP3BitrateToBitrateIndex(unsigned bitrate /* in kbps */,
664 Boolean isMPEG2) {
665 for (unsigned i = 1; i < 15; ++i) {
666 if (live_tabsel[isMPEG2][2][i] >= bitrate)
667 return i;
668 }
669
670 // "bitrate" was larger than any possible, so return the largest possible:
671 return 14;
672}
673
674static void outputHeader(unsigned char* toPtr, unsigned hdr) {
675 toPtr[0] = (unsigned char)(hdr>>24);
676 toPtr[1] = (unsigned char)(hdr>>16);
677 toPtr[2] = (unsigned char)(hdr>>8);
678 toPtr[3] = (unsigned char)(hdr);
679}
680
681static void assignADUBackpointer(MP3FrameParams const& fr,
682 unsigned aduSize,
683 MP3SideInfo& sideInfo,
684 unsigned& availableBytesForBackpointer) {
685 // Give the ADU as large a backpointer as possible:
686 unsigned maxBackpointerSize = fr.isMPEG2 ? 255 : 511;
687
688 unsigned backpointerSize = availableBytesForBackpointer;
689 if (backpointerSize > maxBackpointerSize) {
690 backpointerSize = maxBackpointerSize;
691 }
692
693 // Store the new backpointer now:
694 sideInfo.main_data_begin = backpointerSize;
695
696 // Figure out how many bytes are available for the *next* ADU's backpointer:
697 availableBytesForBackpointer
698 = backpointerSize + fr.frameSize - fr.sideInfoSize ;
699 if (availableBytesForBackpointer < aduSize) {
700 availableBytesForBackpointer = 0;
701 } else {
702 availableBytesForBackpointer -= aduSize;
703 }
704}
705
706unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,
707 unsigned toBitrate,
708 unsigned char* toPtr, unsigned toMaxSize,
709 unsigned& availableBytesForBackpointer) {
710 // Begin by parsing the input ADU's parameters:
711 unsigned hdr, inFrameSize, inSideInfoSize, backpointer, inAduSize;
712 MP3SideInfo sideInfo;
713 if (!GetADUInfoFromMP3Frame(fromPtr, fromSize,
714 hdr, inFrameSize, sideInfo, inSideInfoSize,
715 backpointer, inAduSize)) {
716 return 0;
717 }
718 fromPtr += (4+inSideInfoSize); // skip to 'main data'
719
720 // Alter the 4-byte MPEG header to reflect the output ADU:
721 // (different bitrate; mono; no CRC)
722 Boolean isMPEG2 = ((hdr&0x00080000) == 0);
723 unsigned toBitrateIndex = MP3BitrateToBitrateIndex(toBitrate, isMPEG2);
724 hdr &=~ 0xF000; hdr |= (toBitrateIndex<<12); // set bitrate index
725 hdr |= 0x10200; // turn on !error-prot and padding bits
726 hdr &=~ 0xC0; hdr |= 0xC0; // set mode to 3 (mono)
727
728 // Set up the rest of the parameters of the new ADU:
729 MP3FrameParams outFr;
730 outFr.hdr = hdr;
731 outFr.setParamsFromHeader();
732
733 // Figure out how big to make the output ADU:
734 unsigned inAveAduSize = inFrameSize - inSideInfoSize;
735 unsigned outAveAduSize = outFr.frameSize - outFr.sideInfoSize;
736 unsigned desiredOutAduSize /*=inAduSize*outAveAduSize/inAveAduSize*/
737 = (2*inAduSize*outAveAduSize + inAveAduSize)/(2*inAveAduSize);
738 // this rounds to the nearest integer
739
740 if (toMaxSize < (4 + outFr.sideInfoSize)) return 0;
741 unsigned maxOutAduSize = toMaxSize - (4 + outFr.sideInfoSize);
742 if (desiredOutAduSize > maxOutAduSize) {
743 desiredOutAduSize = maxOutAduSize;
744 }
745
746 // Figure out the new sizes of the various 'part23 lengths',
747 // and how much they are truncated:
748 unsigned part23Length0a, part23Length0aTruncation;
749 unsigned part23Length0b, part23Length0bTruncation;
750 unsigned part23Length1a, part23Length1aTruncation;
751 unsigned part23Length1b, part23Length1bTruncation;
752 unsigned numAduBits
753 = updateSideInfoSizes(sideInfo, outFr.isMPEG2,
754 fromPtr, 8*desiredOutAduSize,
755 part23Length0a, part23Length0aTruncation,
756 part23Length0b, part23Length0bTruncation,
757 part23Length1a, part23Length1aTruncation,
758 part23Length1b, part23Length1bTruncation);
759#ifdef DEBUG
760fprintf(stderr, "shrinkage %d->%d [(%d,%d),(%d,%d)] (trunc: [(%d,%d),(%d,%d)]) {%d}\n", inAduSize, (numAduBits+7)/8,
761 part23Length0a, part23Length0b, part23Length1a, part23Length1b,
762 part23Length0aTruncation, part23Length0bTruncation,
763 part23Length1aTruncation, part23Length1bTruncation,
764 maxOutAduSize);
765#endif
766 unsigned actualOutAduSize = (numAduBits+7)/8;
767
768 // Give the new ADU an appropriate 'backpointer':
769 assignADUBackpointer(outFr, actualOutAduSize, sideInfo, availableBytesForBackpointer);
770
771 ///// Now output the new ADU:
772
773 // 4-byte header
774 outputHeader(toPtr, hdr); toPtr += 4;
775
776 // side info
777 PutMP3SideInfoIntoFrame(sideInfo, outFr, toPtr); toPtr += outFr.sideInfoSize;
778
779 // 'main data', using the new lengths
780 unsigned toBitOffset = 0;
781 unsigned fromBitOffset = 0;
782
783 /* rebuild portion 0a: */
784 memmove(toPtr, fromPtr, (part23Length0a+7)/8);
785 toBitOffset += part23Length0a;
786 fromBitOffset += part23Length0a + part23Length0aTruncation;
787
788 /* rebuild portion 0b: */
789 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length0b);
790 toBitOffset += part23Length0b;
791 fromBitOffset += part23Length0b + part23Length0bTruncation;
792
793 /* rebuild portion 1a: */
794 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1a);
795 toBitOffset += part23Length1a;
796 fromBitOffset += part23Length1a + part23Length1aTruncation;
797
798 /* rebuild portion 1b: */
799 shiftBits(toPtr, toBitOffset, fromPtr, fromBitOffset, part23Length1b);
800 toBitOffset += part23Length1b;
801
802 /* zero out any remaining bits (probably unnecessary, but...) */
803 unsigned char const zero = '\0';
804 shiftBits(toPtr, toBitOffset, &zero, 0,
805 actualOutAduSize*8 - numAduBits);
806
807 return 4 + outFr.sideInfoSize + actualOutAduSize;
808}
809