public void read(BitStream messageBytes) throws CharacterCodingException, IOException { int stackCount = messageBytes.readRangedInt(0, MAX_INT); for (int i = 0; i < stackCount; i++) { SampleStackFrame frame = new SampleStackFrame(); // Get the name. frame.name = messageBytes.readCachedString(); // Filename/line are optionally present. frame.filename = messageBytes.readCachedString(); if (frame.filename != null) frame.fileline = messageBytes.readRangedInt(0, MAX_INT); // Add to the beginning of the stack. frameList.add(0, frame); } }
/** * Fill the sliding dictionary with more data. * * @throws IOException */ private void fillBuffer() throws IOException { init(); int bit = bits.nextBit(); if (bit == 1) { // literal value int literal; if (literalTree != null) { literal = literalTree.read(bits); } else { literal = bits.nextBits(8); } if (literal == -1) { // end of stream reached, nothing left to decode return; } buffer.put(literal); } else if (bit == 0) { // back reference int distanceLowSize = dictionarySize == 4096 ? 6 : 7; int distanceLow = bits.nextBits(distanceLowSize); int distanceHigh = distanceTree.read(bits); if (distanceHigh == -1 && distanceLow <= 0) { // end of stream reached, nothing left to decode return; } int distance = distanceHigh << distanceLowSize | distanceLow; int length = lengthTree.read(bits); if (length == 63) { length += bits.nextBits(8); } length += minimumMatchLength; buffer.copy(distance + 1, length); } }
public void decode(BitStream in) throws AACException { final int start = in.getPosition(); // should be 0 int type; Element prev = null; boolean content = true; if (!config.getProfile().isErrorResilientProfile()) { while (content && (type = in.readBits(3)) != ELEMENT_END) { switch (type) { case ELEMENT_SCE: case ELEMENT_LFE: LOGGER.finest("SCE"); prev = decodeSCE_LFE(in); break; case ELEMENT_CPE: LOGGER.finest("CPE"); prev = decodeCPE(in); break; case ELEMENT_CCE: LOGGER.finest("CCE"); decodeCCE(in); prev = null; break; case ELEMENT_DSE: LOGGER.finest("DSE"); decodeDSE(in); prev = null; break; case ELEMENT_PCE: LOGGER.finest("PCE"); decodePCE(in); prev = null; break; case ELEMENT_FIL: LOGGER.finest("FIL"); decodeFIL(in, prev); prev = null; break; } } LOGGER.finest("END"); content = false; prev = null; } else { // error resilient raw data block switch (config.getChannelConfiguration()) { case CHANNEL_CONFIG_MONO: decodeSCE_LFE(in); break; case CHANNEL_CONFIG_STEREO: decodeCPE(in); break; case CHANNEL_CONFIG_STEREO_PLUS_CENTER: decodeSCE_LFE(in); decodeCPE(in); break; case CHANNEL_CONFIG_STEREO_PLUS_CENTER_PLUS_REAR_MONO: decodeSCE_LFE(in); decodeCPE(in); decodeSCE_LFE(in); break; case CHANNEL_CONFIG_FIVE: decodeSCE_LFE(in); decodeCPE(in); decodeCPE(in); break; case CHANNEL_CONFIG_FIVE_PLUS_ONE: decodeSCE_LFE(in); decodeCPE(in); decodeCPE(in); decodeSCE_LFE(in); break; case CHANNEL_CONFIG_SEVEN_PLUS_ONE: decodeSCE_LFE(in); decodeCPE(in); decodeCPE(in); decodeCPE(in); decodeSCE_LFE(in); break; default: throw new AACException( "unsupported channel configuration for error resilience: " + config.getChannelConfiguration()); } } in.byteAlign(); bitsRead = in.getPosition() - start; }
/** * Calculate the allowed distortion for each scalefactor band, as determined by the psychoacoustic * model. xmin(sb) = ratio(sb) * en(sb) / bw(sb) * * <p>returns number of sfb's with energy > ATH */ public final int calc_xmin( final LameGlobalFlags gfp, final III_psy_ratio ratio, final GrInfo cod_info, final float[] pxmin) { int pxminPos = 0; final LameInternalFlags gfc = gfp.internal_flags; int gsfb, j = 0, ath_over = 0; final ATH ATH = gfc.ATH; final float[] xr = cod_info.xr; final int enable_athaa_fix = (gfp.getVBR() == VbrMode.vbr_mtrh) ? 1 : 0; float masking_lower = gfc.masking_lower; if (gfp.getVBR() == VbrMode.vbr_mtrh || gfp.getVBR() == VbrMode.vbr_mt) { /* was already done in PSY-Model */ masking_lower = 1.0f; } for (gsfb = 0; gsfb < cod_info.psy_lmax; gsfb++) { float en0, xmin; float rh1, rh2; int width, l; if (gfp.getVBR() == VbrMode.vbr_rh || gfp.getVBR() == VbrMode.vbr_mtrh) xmin = athAdjust(ATH.adjust, ATH.l[gsfb], ATH.floor); else xmin = ATH.adjust * ATH.l[gsfb]; width = cod_info.width[gsfb]; rh1 = xmin / width; rh2 = DBL_EPSILON; l = width >> 1; en0 = 0.0f; do { float xa, xb; xa = xr[j] * xr[j]; en0 += xa; rh2 += (xa < rh1) ? xa : rh1; j++; xb = xr[j] * xr[j]; en0 += xb; rh2 += (xb < rh1) ? xb : rh1; j++; } while (--l > 0); if (en0 > xmin) ath_over++; if (gsfb == Encoder.SBPSY_l) { float x = xmin * gfc.nsPsy.longfact[gsfb]; if (rh2 < x) { rh2 = x; } } if (enable_athaa_fix != 0) { xmin = rh2; } if (!gfp.ATHonly) { final float e = ratio.en.l[gsfb]; if (e > 0.0f) { float x; x = en0 * ratio.thm.l[gsfb] * masking_lower / e; if (enable_athaa_fix != 0) x *= gfc.nsPsy.longfact[gsfb]; if (xmin < x) xmin = x; } } if (enable_athaa_fix != 0) pxmin[pxminPos++] = xmin; else pxmin[pxminPos++] = xmin * gfc.nsPsy.longfact[gsfb]; } /* end of long block loop */ /* use this function to determine the highest non-zero coeff */ int max_nonzero = 575; if (cod_info.block_type != Encoder.SHORT_TYPE) { // NORM, START or STOP type, but not SHORT int k = 576; while (k-- != 0 && BitStream.EQ(xr[k], 0)) { max_nonzero = k; } } cod_info.max_nonzero_coeff = max_nonzero; for (int sfb = cod_info.sfb_smin; gsfb < cod_info.psymax; sfb++, gsfb += 3) { int width, b; float tmpATH; if (gfp.getVBR() == VbrMode.vbr_rh || gfp.getVBR() == VbrMode.vbr_mtrh) tmpATH = athAdjust(ATH.adjust, ATH.s[sfb], ATH.floor); else tmpATH = ATH.adjust * ATH.s[sfb]; width = cod_info.width[gsfb]; for (b = 0; b < 3; b++) { float en0 = 0.0f, xmin; float rh1, rh2; int l = width >> 1; rh1 = tmpATH / width; rh2 = DBL_EPSILON; do { float xa, xb; xa = xr[j] * xr[j]; en0 += xa; rh2 += (xa < rh1) ? xa : rh1; j++; xb = xr[j] * xr[j]; en0 += xb; rh2 += (xb < rh1) ? xb : rh1; j++; } while (--l > 0); if (en0 > tmpATH) ath_over++; if (sfb == Encoder.SBPSY_s) { float x = tmpATH * gfc.nsPsy.shortfact[sfb]; if (rh2 < x) { rh2 = x; } } if (enable_athaa_fix != 0) xmin = rh2; else xmin = tmpATH; if (!gfp.ATHonly && !gfp.ATHshort) { final float e = ratio.en.s[sfb][b]; if (e > 0.0f) { float x; x = en0 * ratio.thm.s[sfb][b] * masking_lower / e; if (enable_athaa_fix != 0) x *= gfc.nsPsy.shortfact[sfb]; if (xmin < x) xmin = x; } } if (enable_athaa_fix != 0) pxmin[pxminPos++] = xmin; else pxmin[pxminPos++] = xmin * gfc.nsPsy.shortfact[sfb]; } /* b */ if (gfp.useTemporal) { if (pxmin[pxminPos - 3] > pxmin[pxminPos - 3 + 1]) pxmin[pxminPos - 3 + 1] += (pxmin[pxminPos - 3] - pxmin[pxminPos - 3 + 1]) * gfc.decay; if (pxmin[pxminPos - 3 + 1] > pxmin[pxminPos - 3 + 2]) pxmin[pxminPos - 3 + 2] += (pxmin[pxminPos - 3 + 1] - pxmin[pxminPos - 3 + 2]) * gfc.decay; } } /* end of short block sfb loop */ return ath_over; }
/* * Parse stream headers until a compressed block or end of stream is reached. Possible return codes: OK - a * compressed block was found FINISH - end of stream was reached MORE - more input is need, parsing was suspended * ERR_HEADER - invalid stream header ERR_STRMCRC - stream CRC does not match ERR_EOF - unterminated stream (EOF * reached before end of stream) garbage is set only when returning FINISH. It is number of garbage bits consumed * after end of stream was reached. */ Status parse(Header hd, BitStream bs, int[] garbage) throws StreamFormatException { assert (state != ACCEPT); while (OK == bs.need(16)) { int word = bs.peek(16); bs.dump(16); switch (state) { case STREAM_MAGIC_1: if (0x425A != word) { hd.bs100k = -1; hd.crc = 0; state = ACCEPT; garbage[0] = 16; return FINISH; } state = STREAM_MAGIC_2; continue; case STREAM_MAGIC_2: if (0x6839 < word || 0x6831 > word) { hd.bs100k = -1; hd.crc = 0; state = ACCEPT; garbage[0] = 32; return FINISH; } bs100k = word & 0xF; state = BLOCK_MAGIC_1; continue; case BLOCK_MAGIC_1: if (0x1772 == word) { state = EOS_2; continue; } if (0x3141 != word) throw new StreamFormatException("ERR_HEADER"); state = BLOCK_MAGIC_2; continue; case BLOCK_MAGIC_2: if (0x5926 != word) throw new StreamFormatException("ERR_HEADER"); state = BLOCK_MAGIC_3; continue; case BLOCK_MAGIC_3: if (0x5359 != word) throw new StreamFormatException("ERR_HEADER"); state = BLOCK_CRC_1; continue; case BLOCK_CRC_1: stored_crc = word; state = BLOCK_CRC_2; continue; case BLOCK_CRC_2: hd.crc = (stored_crc << 16) | word; hd.bs100k = bs100k; computed_crc = (computed_crc << 1) ^ (computed_crc >>> 31) ^ hd.crc; state = BLOCK_MAGIC_1; return OK; case EOS_2: if (0x4538 != word) throw new StreamFormatException("ERR_HEADER"); state = EOS_3; continue; case EOS_3: if (0x5090 != word) throw new StreamFormatException("ERR_HEADER"); state = EOS_CRC_1; continue; case EOS_CRC_1: stored_crc = word; state = EOS_CRC_2; continue; case EOS_CRC_2: stored_crc = (stored_crc << 16) | word; if (stored_crc != computed_crc) throw new StreamFormatException("ERR_STRMCRC"); computed_crc = 0; bs.align(); state = STREAM_MAGIC_1; continue; default: break; } throw new IllegalStateException(); } if (FINISH != bs.need(16)) return MORE; if (state == STREAM_MAGIC_1) { state = ACCEPT; garbage[0] = 0; return FINISH; } if (state == STREAM_MAGIC_2) { state = ACCEPT; garbage[0] = 16; return FINISH; } throw new StreamFormatException("ERR_EOF"); }