private void computeBandIndexes(Granule g) { if (g.blockType == 2) { if (g.switchPoint != 0) { if (ctx.header.sampleRateIndex == 8) { log.warn(String.format("Unimplemented switch point in 8kHz")); } // if switched mode, we handle the 36 first samples as // long blocks. For 8000Hz, we handle the 72 first // exponents as long blocks if (ctx.header.sampleRateIndex <= 2) { g.longEnd = 8; } else { g.longEnd = 6; } g.shortStart = 3; } else { g.longEnd = 0; g.shortStart = 0; } } else { g.shortStart = 13; g.longEnd = 22; } }
// main layer3 decoding function private int decodeLayer3(int frameStart) { int mainDataBegin; int nbGranules; int[] exponents = new int[576]; Mp3Header s = ctx.header; // read side info if (s.lsf != 0) { mainDataBegin = br.read(8); br.skip(s.nbChannels); nbGranules = 1; } else { mainDataBegin = br.read(9); if (s.nbChannels == 2) { br.skip(3); } else { br.skip(5); } nbGranules = 2; for (int ch = 0; ch < s.nbChannels; ch++) { ctx.granules[ch][0].scfsi = 0; // all scale factors are transmitted ctx.granules[ch][1].scfsi = br.read(4); } } for (int gr = 0; gr < nbGranules; gr++) { for (int ch = 0; ch < s.nbChannels; ch++) { Granule g = ctx.granules[ch][gr]; g.part23Length = br.read(12); g.bigValues = br.read(9); if (g.bigValues > 288) { log.error(String.format("bigValues too big %d", g.bigValues)); return MP3_ERROR; } g.globalGain = br.read(8); // if MS stereo only is selected, we precompute the // 1/sqrt(2) renormalization factor if ((s.modeExt & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) == MODE_EXT_MS_STEREO) { g.globalGain -= 2; } if (s.lsf != 0) { g.scalefacCompress = br.read(9); } else { g.scalefacCompress = br.read(4); } boolean blocksplitFlag = br.readBool(); if (blocksplitFlag) { g.blockType = br.read(2); if (g.blockType == 0) { log.error(String.format("invalid block type")); return MP3_ERROR; } g.switchPoint = br.read1(); for (int i = 0; i < 2; i++) { g.tableSelect[i] = br.read(5); } for (int i = 0; i < 3; i++) { g.subblockGain[i] = br.read(3); } initShortRegion(g); } else { g.blockType = 0; g.switchPoint = 0; for (int i = 0; i < 3; i++) { g.tableSelect[i] = br.read(5); } // compute Huffman coded region sizes int regionAddress1 = br.read(4); int regionAddress2 = br.read(3); initLongRegion(g, regionAddress1, regionAddress2); } regionOffset2size(g); computeBandIndexes(g); g.preflag = 0; if (s.lsf == 0) { g.preflag = br.read1(); } g.scalefacScale = br.read1(); g.count1tableSelect = br.read1(); } } if (ctx.aduMode == 0) { int currentPosition = br.getBytesRead(); int copyLength = ctx.header.frameSize - (currentPosition - frameStart); int bitsToSkip = bb.getBitsWritten() - bb.getBitsRead() - (mainDataBegin << 3); for (int i = 0; i < copyLength; i++) { bb.writeByte(br.readByte()); } bb.skip(bitsToSkip); } for (int gr = 0; gr < nbGranules; gr++) { for (int ch = 0; ch < s.nbChannels; ch++) { Granule g = ctx.granules[ch][gr]; g.granuleStartPosition = bb.getBitsRead(); if (s.lsf == 0) { // MPEG1 scale factors int slen1 = slen_table[0][g.scalefacCompress]; int slen2 = slen_table[1][g.scalefacCompress]; if (g.blockType == 2) { int n = g.switchPoint != 0 ? 17 : 18; int j = 0; if (slen1 != 0) { for (int i = 0; i < n; i++) { g.scaleFactors[j++] = bb.read(slen1); } } else { for (int i = 0; i < n; i++) { g.scaleFactors[j++] = 0; } } if (slen2 != 0) { for (int i = 0; i < 18; i++) { g.scaleFactors[j++] = bb.read(slen2); } for (int i = 0; i < 3; i++) { g.scaleFactors[j++] = 0; } } else { for (int i = 0; i < 21; i++) { g.scaleFactors[j++] = 0; } } } else { int sc[] = ctx.granules[ch][0].scaleFactors; int j = 0; for (int k = 0; k < 4; k++) { int n = (k == 0 ? 6 : 5); if ((g.scfsi & (0x8 >> k)) == 0) { int slen = (k < 2 ? slen1 : slen2); if (slen != 0) { for (int i = 0; i < n; i++) { g.scaleFactors[j++] = bb.read(slen); } } else { for (int i = 0; i < n; i++) { g.scaleFactors[j++] = 0; } } } else { // simple copy from last granule for (int i = 0; i < n; i++) { g.scaleFactors[j] = sc[j]; j++; } } } g.scaleFactors[j++] = 0; } } else { int tindex; int tindex2; int[] slen = new int[4]; // LSF scale factors if (g.blockType == 2) { tindex = g.switchPoint != 0 ? 2 : 1; } else { tindex = 0; } int sf = g.scalefacCompress; if ((s.modeExt & MODE_EXT_I_STEREO) != 0 && ch == 1) { // intensity stereo case sf >>= 1; if (sf < 180) { lsfSfExpand(slen, sf, 6, 6, 0); tindex2 = 3; } else if (sf < 244) { lsfSfExpand(slen, sf - 180, 4, 4, 0); tindex2 = 4; } else { lsfSfExpand(slen, sf - 244, 3, 0, 0); tindex2 = 5; } } else { // normal case if (sf < 400) { lsfSfExpand(slen, sf, 5, 4, 4); tindex2 = 0; } else if (sf < 500) { lsfSfExpand(slen, sf - 400, 5, 4, 0); tindex2 = 1; } else { lsfSfExpand(slen, sf - 500, 3, 0, 0); tindex2 = 2; g.preflag = 1; } } int j = 0; for (int k = 0; k < 4; k++) { int n = lsf_nsf_table[tindex2][tindex][k]; int sl = slen[k]; if (sl != 0) { for (int i = 0; i < n; i++) { g.scaleFactors[j++] = bb.read(sl); } } else { for (int i = 0; i < n; i++) { g.scaleFactors[j++] = 0; } } } for (; j < 40; j++) { g.scaleFactors[j] = 0; } } exponentsFromScaleFactors(g, exponents); // read Huffman coded residue huffmanDecode(g, exponents); } if (s.mode == MP3_JSTEREO) { computeStereo(ctx.granules[0][gr], ctx.granules[1][gr]); } for (int ch = 0; ch < s.nbChannels; ch++) { Granule g = ctx.granules[ch][gr]; reorderBlock(g); computeAntialias(g); computeImdct(g, ctx.sbSamples[ch], 18 * gr * SBLIMIT, ctx.mdctBuf[ch]); } } return nbGranules * 18; }