void decode(BitStream inStream, DecoderConfig conf) { couplingPoint = 2 * inStream.readBit(); coupledCount = inStream.readBits(3); int gainCount = 0; for (int i = 0; i <= coupledCount; i++) { gainCount++; channelPair[i] = inStream.readBool(); idSelect[i] = inStream.readBits(4); if (channelPair[i]) { chSelect[i] = inStream.readBits(2); if (chSelect[i] == 3) { gainCount++; } } else { chSelect[i] = 2; } } couplingPoint += inStream.readBit(); couplingPoint |= (couplingPoint >> 1); bool sign = inStream.readBool(); double scale = CCE_SCALE[inStream.readBits(2)]; ics.decode(inStream, false, conf); ICSInfo info = ics.getInfo(); int windowGroupCount = info.getWindowGroupCount(); int maxSFB = info.getMaxSFB(); //TODO: int[,] sfbCB = null;//ics.getSectionData().getSfbCB(); for (int i = 0; i < gainCount; i++) { int idx = 0; int cge = 1; int xg = 0; float gainCache = 1.0f; if (i > 0) { cge = couplingPoint == 2 ? 1 : inStream.readBit(); xg = cge == 0 ? 0 : Huffman.decodeScaleFactor(inStream) - 60; gainCache = (float)Math.Pow(scale, -xg); } if (couplingPoint == 2) { gain[i, 0] = gainCache; } else { for (int g = 0; g < windowGroupCount; g++) { for (int sfb = 0; sfb < maxSFB; sfb++, idx++) { if (sfbCB[g, sfb] != ZERO_HCB) { if (cge == 0) { int t = Huffman.decodeScaleFactor(inStream) - 60; if (t != 0) { int s = 1; t = xg += t; if (!sign) { s -= 2 * (t & 0x1); t >>= 1; } gainCache = (float)(Math.Pow(scale, -t) * s); } } gain[i, idx] = gainCache; } } } } } }
// private void decodePulseData(BitStream in) throws AACException { // pulseCount = in.readBits(2)+1; // pulseStartSWB = in.readBits(6); // if(pulseStartSWB>=info.getSWBCount()) throw new AACException("pulse SWB out of range: "+pulseStartSWB+" > "+info.getSWBCount()); // if(pulseOffset==null||pulseCount!=pulseOffset.Length) { // //only reallocate if needed // pulseOffset = new int[pulseCount]; // pulseAmp = new int[pulseCount]; // } // pulseOffset[0] = info.getSWBOffsets()[pulseStartSWB]; // pulseOffset[0] += in.readBits(5); // pulseAmp[0] = in.readBits(4); // for(int i = 1; i<pulseCount; i++) { // pulseOffset[i] = in.readBits(5)+pulseOffset[i-1]; // if(pulseOffset[i]>1023) throw new AACException("pulse offset out of range: "+pulseOffset[0]); // pulseAmp[i] = in.readBits(4); // } // } public void decodeScaleFactors(BitStream inStream) { int windowGroups = info.getWindowGroupCount(); int maxSFB = info.getMaxSFB(); //0: spectrum, 1: noise, 2: intensity int[] offset = { globalGain, globalGain - 90, 0 }; int tmp; bool noiseFlag = true; int sfb, idx = 0; for (int g = 0; g < windowGroups; g++) { for (sfb = 0; sfb < maxSFB;) { int end = sectEnd[idx]; switch (sfbCB[idx]) { case ZERO_HCB: { for (; sfb < end; sfb++, idx++) { scaleFactors[idx] = 0; } } break; case INTENSITY_HCB: case INTENSITY_HCB2: { for (; sfb < end; sfb++, idx++) { offset[2] += Huffman.decodeScaleFactor(inStream) - SF_DELTA; tmp = Math.Min(Math.Max(offset[2], -155), 100); scaleFactors[idx] = SCALEFACTOR_TABLE[-tmp + SF_OFFSET]; } } break; case NOISE_HCB: { throw new NotImplementedException(); //for (; sfb < end; sfb++, idx++) //{ // if (noiseFlag) // { // offset[1] += inStream.readBits(9) - 256; // noiseFlag = false; // } // else offset[1] += Huffman.decodeScaleFactor(inStream) - SF_DELTA; // tmp = Math.min(Math.max(offset[1], -100), 155); // scaleFactors[idx] = -SCALEFACTOR_TABLE[tmp + SF_OFFSET]; //} } break; default: { for (; sfb < end; sfb++, idx++) { offset[0] += Huffman.decodeScaleFactor(inStream) - SF_DELTA; if (offset[0] > 255) { throw new AACException("scalefactor out of range: " + offset[0]); } scaleFactors[idx] = SCALEFACTOR_TABLE[offset[0] - 100 + SF_OFFSET]; } } break; } } } }