Example #1
0
 boolean isChecksumError() {
   if (header.getProtection() == Header.MPEG_PROTECTION_CRC) {
     if (header.getLayer() == Header.MPEG_LAYER_3) {
       CRC16 crc16 = new CRC16();
       crc16.update(bytes[2]);
       crc16.update(bytes[3]);
       // skip crc bytes 4+5
       int sideInfoSize = header.getSideInfoSize();
       for (int i = 0; i < sideInfoSize; i++) {
         crc16.update(bytes[6 + i]);
       }
       int crc = ((bytes[4] & 0xFF) << 8) | (bytes[5] & 0xFF);
       return crc != crc16.getValue();
     }
   }
   return false;
 }
Example #2
0
 public ReadPacket(byte[] readPacket) {
   this.command = readPacket[OFFSET_CMD];
   this.data = Arrays.copyOfRange(readPacket, OFFSET_DATA, readPacket.length - CRC_LEN);
   this.crc = Arrays.copyOfRange(readPacket, readPacket.length - CRC_LEN, readPacket.length);
   this.crc_calc = CRC16.calculate(readPacket, 0, readPacket.length - 2);
   if (!Arrays.equals(this.crc, this.crc_calc)) {
     throw new CRCFailRuntimeException(
         "CRC check failed: "
             + Utils.bytesToHex(this.crc)
             + " vs "
             + Utils.bytesToHex(this.crc_calc));
   }
 }
 public boolean parse(byte[] data, int ofs) {
   final int origOfs = ofs;
   int fh32 =
       (data[ofs] << 24)
           | ((data[ofs + 1] & 0xFF) << 16)
           | ((data[ofs + 2] & 0xFF) << 8)
           | (data[ofs + 3] & 0xFF);
   FrameHeader fh = new FrameHeader(fh32);
   ofs += 4 + fh.getSideInfoSize();
   boolean xingTag =
       (data[ofs] == 0x58) // 'Xing'
           && (data[ofs + 1] == 0x69)
           && (data[ofs + 2] == 0x6E)
           && (data[ofs + 3] == 0x67);
   boolean infoTag =
       (data[ofs] == 0x49) // 'Info'
           && (data[ofs + 1] == 0x6E)
           && (data[ofs + 2] == 0x66)
           && (data[ofs + 3] == 0x6F);
   if (!xingTag && !infoTag) {
     return false;
   }
   ofs += 4;
   this.xingTag = xingTag;
   this.infoTag = infoTag;
   this.frameSize = fh.getFrameSize();
   System.arraycopy(data, origOfs, bb, 0, frameSize);
   int flags = data[ofs + 3] & 0xFF;
   ofs += 4;
   if ((flags & 0x01) != 0) ofs += 4; // skip frame count
   if ((flags & 0x02) != 0) ofs += 4; // skip byte count
   if ((flags & 0x04) != 0) ofs += 100; // skip seek table
   if ((flags & 0x08) != 0) ofs += 4; // skip VBR scale
   int tagEndOfs = ofs + 0x24;
   int crc = 0;
   for (int i = origOfs; i < tagEndOfs - 2; i++) {
     crc = CRC16.updateLAME(crc, data[i] & 0xFF);
   }
   this.lameTag =
       (data[ofs] == 0x4C)
           && (data[ofs + 1] == 0x41)
           && (data[ofs + 2] == 0x4D)
           && (data[ofs + 3] == 0x45);
   if (!this.lameTag) {
     this.lameTag =
         (data[ofs] == 0x47)
             && (data[ofs + 1] == 0x4F)
             && (data[ofs + 2] == 0x47)
             && (data[ofs + 3] == 0x4F);
   }
   this.lameTag |=
       ((((data[tagEndOfs - 2] << 8) | (data[tagEndOfs - 1] & 0xFF)) ^ crc) & 0xFFFF) == 0;
   if (this.lameTag) {
     lameTagOfs = ofs - origOfs - 4;
   }
   ofs += 0x15;
   int t = data[ofs + 1] & 0xFF;
   encDelay = ((data[ofs] & 0xFF) << 4) | (t >>> 4);
   encPadding = ((t & 0x0F) << 8) | (data[ofs + 2] & 0xFF);
   if (!this.lameTag) {
     if (encDelay > 2880 || encPadding > 2304) {
       encDelay = 576;
       encPadding = 0;
     }
   }
   return true;
 }
 public static int createHeaderFrame(
     FrameHeader toBeSimilar,
     boolean vbr,
     float kbps,
     int frameCount,
     int musicBytes,
     int vbrScale,
     byte[] seektable,
     int encDelay,
     int encPadding,
     XingInfoLameTagFrame srcTag,
     byte[] dest,
     final int dofs,
     final int maskATH) {
   int fh32 = toBeSimilar.getHeader32() | 0x00010000; // disable CRC if any
   int frameSize = 0;
   int tagOffset = 0;
   { // calculate optimal header frame size
     FrameHeader tmp = new FrameHeader();
     float minDist = 9999;
     for (int i = 1; i < 15; i++) {
       int th32 = (fh32 & 0xFFFF0FFF) | (i << 12);
       tmp.setHeader32(th32);
       if (tmp.getFrameSize() >= 0xC0) {
         int ikbps = tmp.getBitrateKBPS();
         float dist = Math.abs(kbps - ikbps);
         if (dist < minDist) {
           minDist = dist;
           fh32 = th32;
           frameSize = tmp.getFrameSize();
           tagOffset = tmp.getSideInfoSize() + 4;
         }
       }
     }
   }
   tagOffset += dofs;
   Arrays.fill(dest, dofs, dofs + frameSize, (byte) 0);
   dest[dofs] = (byte) (fh32 >>> 24);
   dest[dofs + 1] = (byte) (fh32 >>> 16);
   dest[dofs + 2] = (byte) (fh32 >>> 8);
   dest[dofs + 3] = (byte) fh32;
   if (vbr) {
     dest[tagOffset++] = (byte) 0x58; // X
     dest[tagOffset++] = (byte) 0x69; // i
     dest[tagOffset++] = (byte) 0x6E; // n
     dest[tagOffset++] = (byte) 0x67; // g
   } else {
     dest[tagOffset++] = (byte) 0x49; // I
     dest[tagOffset++] = (byte) 0x6E; // n
     dest[tagOffset++] = (byte) 0x66; // f
     dest[tagOffset++] = (byte) 0x6F; // o
   }
   dest[tagOffset++] = 0;
   dest[tagOffset++] = 0;
   dest[tagOffset++] = 0;
   dest[tagOffset++] = 0x0F;
   dest[tagOffset++] = (byte) (frameCount >>> 24);
   dest[tagOffset++] = (byte) (frameCount >>> 16);
   dest[tagOffset++] = (byte) (frameCount >>> 8);
   dest[tagOffset++] = (byte) frameCount;
   int temp = frameSize + musicBytes;
   dest[tagOffset++] = (byte) (temp >>> 24);
   dest[tagOffset++] = (byte) (temp >>> 16);
   dest[tagOffset++] = (byte) (temp >>> 8);
   dest[tagOffset++] = (byte) temp;
   System.arraycopy(seektable, 0, dest, tagOffset, 100);
   tagOffset += 100;
   dest[tagOffset++] = (byte) (vbrScale >>> 24);
   dest[tagOffset++] = (byte) (vbrScale >>> 16);
   dest[tagOffset++] = (byte) (vbrScale >>> 8);
   dest[tagOffset++] = (byte) vbrScale;
   if (srcTag != null && srcTag.isValid() && srcTag.lameTagPresent()) {
     System.arraycopy(srcTag.bb, srcTag.lameTagOfs, dest, tagOffset - 4, 40);
     tagOffset += 4;
     // delete LAME's replaygain tag
     for (int i = 0; i < 8; i++) {
       dest[tagOffset + 0x07 + i] = 0;
     }
     // deleting no-gap flags ...
     dest[tagOffset + 0x0F] &= maskATH;
   } else {
     dest[tagOffset++] = (byte) 0x4C; // L
     dest[tagOffset++] = (byte) 0x41; // A
     dest[tagOffset++] = (byte) 0x4D; // M
     dest[tagOffset++] = (byte) 0x45; // E
   }
   encDelay = Math.max(0, Math.min(encDelay, 4095));
   encPadding = Math.max(0, Math.min(encPadding, 4095));
   // write encDelay / encPadding ...
   dest[tagOffset + 0x11] = (byte) (encDelay >>> 4);
   dest[tagOffset + 0x12] = (byte) ((encDelay & 0xF) << 4 | (encPadding >>> 8));
   dest[tagOffset + 0x13] = (byte) encPadding;
   temp = frameSize + musicBytes;
   dest[tagOffset + 0x18] = (byte) (temp >>> 24);
   dest[tagOffset + 0x19] = (byte) (temp >>> 16);
   dest[tagOffset + 0x1A] = (byte) (temp >>> 8);
   dest[tagOffset + 0x1B] = (byte) temp;
   int crc = 0;
   for (int i = 0; i < 190; i++) {
     crc = CRC16.updateLAME(crc, dest[dofs + i] & 0xFF);
   }
   dest[tagOffset + 0x1E] = (byte) (crc >>> 8);
   dest[tagOffset + 0x1F] = (byte) crc;
   return frameSize;
 }