private int decodeFrame(int frameStart) { int nbFrames; if (ctx.header.errorProtection != 0) { br.skip(16); } switch (ctx.header.layer) { case 1: nbFrames = decodeLayer1(); break; case 2: nbFrames = decodeLayer2(); break; case 3: default: nbFrames = decodeLayer3(frameStart); break; } if (nbFrames < 0) { return nbFrames; } // get output buffer if (ctx.samples == null) { ctx.samples = new float[ctx.header.nbChannels][ctx.header.maxSamples]; } // apply the synthesis filter for (int ch = 0; ch < ctx.header.nbChannels; ch++) { int sampleStride = 1; int samplesPtr = 0; for (int i = 0; i < nbFrames; i++) { Mp3Dsp.synthFilter( ctx, ch, ctx.samples[ch], samplesPtr, sampleStride, ctx.sbSamples[ch], i * SBLIMIT); samplesPtr += 32 * sampleStride; } } return nbFrames * 32 * 4 * ctx.header.nbChannels; }
private void initStatic() { if (initializedTables) { return; } // scale factors table for layer 1/2 for (int i = 0; i < 64; i++) { // 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS int shift = i / 3; int mod = i % 3; scale_factor_modshift[i] = mod | (shift << 2); } // scale factor multiply for layer 1 for (int i = 0; i < 15; i++) { int n = i + 2; int norm = (int) (((1L << n) * FRAC_ONE) / ((1 << n) - 1)); scale_factor_mult[i][0] = (int) (norm * 1.0f * 2.0f); scale_factor_mult[i][1] = (int) (norm * 0.7937005259f * 2.0f); scale_factor_mult[i][2] = (int) (norm * 0.6299605249f * 2.0f); } Mp3Dsp.synthInit(Mp3Dsp.mpa_synth_window); // Huffman decode tables for (int i = 1; i < 16; i++) { HuffTable h = Mp3Data.mpa_huff_tables[i]; int[] tmpBits = new int[512]; int[] tmpCodes = new int[512]; int xsize = h.xsize; int j = 0; for (int x = 0; x < xsize; x++) { for (int y = 0; y < xsize; y++) { tmpBits[(x << 5) | y | ((x != 0 && y != 0) ? 16 : 0)] = h.bits[j]; tmpCodes[(x << 5) | y | ((x != 0 && y != 0) ? 16 : 0)] = h.codes[j++]; } } huff_vlc[i] = new VLC(); huff_vlc[i].initVLCSparse(7, 512, tmpBits, tmpCodes, null); } for (int i = 0; i < 2; i++) { huff_quad_vlc[i] = new VLC(); huff_quad_vlc[i].initVLCSparse(i == 0 ? 7 : 4, 16, mpa_quad_bits[i], mpa_quad_codes[i], null); } for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < 22; j++) { band_index_long[i][j] = k; k += band_size_long[i][j]; } band_index_long[i][22] = k; } Mp3Data.tableinit(); Mp3Dsp.initMpadspTabs(); for (int i = 0; i < 4; i++) { if (mp3_quant_bits[i] < 0) { for (int j = 0; j < (1 << (-mp3_quant_bits[i] + 1)); j++) { int val = j; int steps = Mp3Data.mp3_quant_steps[i]; int val1 = val % steps; val /= steps; int val2 = val % steps; int val3 = val / steps; division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8); } } } for (int i = 0; i < 7; i++) { float v; if (i != 6) { float f = (float) Math.tan(i * Math.PI / 12.0); v = f / (1f + f); } else { v = 1f; } is_table[0][i] = v; is_table[1][6 - i] = v; } // invalid values for (int i = 7; i < 16; i++) { is_table[0][i] = 0f; is_table[1][i] = 0f; } for (int i = 0; i < 16; i++) { for (int j = 0; j < 2; j++) { int e = -(j + 1) * ((i + 1) >> 1); double f = pow(2.0, e / 4.0); int k = i & 1; is_table_lsf[j][k ^ 1][i] = (float) f; is_table_lsf[j][k][i] = 1f; } } for (int i = 0; i < 8; i++) { float ci = ci_table[i]; float cs = (float) (1.0 / Math.sqrt(1.0 + ci * ci)); float ca = cs * ci; csa_table[i][0] = cs; csa_table[i][1] = ca; csa_table[i][2] = ca + cs; csa_table[i][3] = ca - cs; } initializedTables = true; }
private void computeImdct(Granule g, float[] sbSamples, int sbSamplesOffset, float[] mdctbuf) { float out2[] = new float[12]; // find last non zero block int ptr = 576; int ptr1 = 2 * 18; float[] p = g.sbHybrid; while (ptr >= ptr1) { ptr -= 6; if (p[ptr] != 0f || p[ptr + 1] != 0f || p[ptr + 2] != 0f || p[ptr + 3] != 0f || p[ptr + 4] != 0f || p[ptr + 5] != 0f) { break; } } int sblimit = ptr / 18 + 1; int mdctLongEnd; if (g.blockType == 2) { if (g.switchPoint != 0) { mdctLongEnd = 2; } else { mdctLongEnd = 0; } } else { mdctLongEnd = sblimit; } Mp3Dsp.imdct36Blocks( sbSamples, sbSamplesOffset, mdctbuf, 0, g.sbHybrid, 0, mdctLongEnd, g.switchPoint, g.blockType); int buf = 4 * 18 * (mdctLongEnd >> 2) + (mdctLongEnd & 3); ptr = 18 * mdctLongEnd; for (int j = mdctLongEnd; j < sblimit; j++) { // select frequency inversion float win[] = mdct_win[2 + (4 & -(j & 1))]; int outPtr = j; for (int i = 0; i < 6; i++) { sbSamples[outPtr] = mdctbuf[buf + 4 * i]; outPtr += SBLIMIT; } imdct12(out2, 0, g.sbHybrid, ptr + 0); for (int i = 0; i < 6; i++) { sbSamples[outPtr] = out2[i] * win[i] + mdctbuf[buf + 4 * (i + 6 * 1)]; mdctbuf[buf + 4 * (i + 6 * 2)] = out2[i + 6] * win[i + 6]; outPtr += SBLIMIT; } imdct12(out2, 0, g.sbHybrid, ptr + 1); for (int i = 0; i < 6; i++) { sbSamples[outPtr] = out2[i] * win[i] + mdctbuf[buf + 4 * (i + 6 * 2)]; mdctbuf[buf + 4 * (i + 6 * 0)] = out2[i + 6] * win[i + 6]; outPtr += SBLIMIT; } imdct12(out2, 0, g.sbHybrid, ptr + 2); for (int i = 0; i < 6; i++) { mdctbuf[buf + 4 * (i + 6 * 0)] = out2[i] * win[i] + mdctbuf[buf + 4 * (i + 6 * 0)]; mdctbuf[buf + 4 * (i + 6 * 1)] = out2[i + 6] * win[i + 6]; mdctbuf[buf + 4 * (i + 6 * 2)] = 0f; } ptr += 18; buf += (j & 3) != 3 ? 1 : (4 * 18 - 3); } // zero bands for (int j = sblimit; j < SBLIMIT; j++) { // overlap int outPtr = j; for (int i = 0; i < 18; i++) { sbSamples[outPtr] = mdctbuf[buf + 4 * i]; mdctbuf[buf + 4 * i] = 0f; outPtr += SBLIMIT; } buf += (j & 3) != 3 ? 1 : (4 * 18 - 3); } }