Example #1
0
  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;
    }
  }
Example #2
0
  // 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;
  }