net.sourceforge.jaad.aac.syntax.ICSInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcodec Show documentation
Show all versions of jcodec Show documentation
Pure Java implementation of video/audio codecs and formats
package net.sourceforge.jaad.aac.syntax;
import static net.sourceforge.jaad.aac.Profile.*;
import org.jcodec.platform.Platform;
import net.sourceforge.jaad.aac.AACException;
import net.sourceforge.jaad.aac.DecoderConfig;
import net.sourceforge.jaad.aac.Profile;
import net.sourceforge.jaad.aac.SampleFrequency;
import net.sourceforge.jaad.aac.tools.ICPrediction;
import static java.lang.System.arraycopy;
import org.jcodec.platform.Platform;
import net.sourceforge.jaad.aac.AACException;
import net.sourceforge.jaad.aac.Profile;
import net.sourceforge.jaad.aac.SampleFrequency;
import net.sourceforge.jaad.aac.filterbank.FilterBank;
import net.sourceforge.jaad.aac.syntax.IBitStream;
import net.sourceforge.jaad.aac.syntax.ICSInfo;
import net.sourceforge.jaad.aac.syntax.ICStream;
import net.sourceforge.jaad.aac.syntax.SyntaxConstants;
/**
* This class is part of JAAD ( jaadec.sourceforge.net ) that is distributed
* under the Public Domain license. Code changes provided by the JCodec project
* are distributed under FreeBSD license.
*
* @author in-somnia
*/
public class ICSInfo implements SyntaxConstants, ScaleFactorBands {
public static class LTPrediction implements SyntaxConstants {
private static final float[] CODEBOOK = {
0.570829f,
0.696616f,
0.813004f,
0.911304f,
0.984900f,
1.067894f,
1.194601f,
1.369533f
};
private final int frameLength;
private final int[] states;
private int coef, lag, lastBand;
private boolean lagUpdate;
private boolean[] shortUsed, shortLagPresent, longUsed;
private int[] shortLag;
public LTPrediction(int frameLength) {
this.frameLength = frameLength;
states = new int[4*frameLength];
}
public void decode(IBitStream _in, ICSInfo info, Profile profile) throws AACException {
lag = 0;
if(profile.equals(Profile.AAC_LD)) {
lagUpdate = _in.readBool();
if(lagUpdate) lag = _in.readBits(10);
}
else lag = _in.readBits(11);
if(lag>(frameLength<<1)) throw new AACException("LTP lag too large: "+lag);
coef = _in.readBits(3);
final int windowCount = info.getWindowCount();
if(info.isEightShortFrame()) {
shortUsed = new boolean[windowCount];
shortLagPresent = new boolean[windowCount];
shortLag = new int[windowCount];
for(int w = 0; w= values.length) {
throw new AACException("unknown window sequence type");
}
return values[i];
}
private final int frameLength;
private WindowSequence windowSequence;
private int[] windowShape;
private int maxSFB;
//prediction
private boolean predictionDataPresent;
private ICPrediction icPredict;
boolean ltpData1Present, ltpData2Present;
private LTPrediction ltPredict1, ltPredict2;
//windows/sfbs
private int windowCount;
private int windowGroupCount;
private int[] windowGroupLength;
private int swbCount;
private int[] swbOffsets;
public ICSInfo(int frameLength) {
this.frameLength = frameLength;
windowShape = new int[2];
windowSequence = WindowSequence.ONLY_LONG_SEQUENCE;
windowGroupLength = new int[MAX_WINDOW_GROUP_COUNT];
ltpData1Present = false;
ltpData2Present = false;
}
/* ========== decoding ========== */
public void decode(IBitStream _in, DecoderConfig conf, boolean commonWindow) throws AACException {
final SampleFrequency sf = conf.getSampleFrequency();
if(sf.equals(SampleFrequency.SAMPLE_FREQUENCY_NONE)) throw new AACException("invalid sample frequency");
_in.skipBit(); //reserved
windowSequence = windowSequenceFromInt(_in.readBits(2));
windowShape[PREVIOUS] = windowShape[CURRENT];
windowShape[CURRENT] = _in.readBit();
windowGroupCount = 1;
windowGroupLength[0] = 1;
if(windowSequence.equals(WindowSequence.EIGHT_SHORT_SEQUENCE)) {
maxSFB = _in.readBits(4);
int i;
for(i = 0; i<7; i++) {
if(_in.readBool()) windowGroupLength[windowGroupCount-1]++;
else {
windowGroupCount++;
windowGroupLength[windowGroupCount-1] = 1;
}
}
windowCount = 8;
swbOffsets = SWB_OFFSET_SHORT_WINDOW[sf.getIndex()];
swbCount = SWB_SHORT_WINDOW_COUNT[sf.getIndex()];
predictionDataPresent = false;
}
else {
maxSFB = _in.readBits(6);
windowCount = 1;
swbOffsets = SWB_OFFSET_LONG_WINDOW[sf.getIndex()];
swbCount = SWB_LONG_WINDOW_COUNT[sf.getIndex()];
predictionDataPresent = _in.readBool();
if(predictionDataPresent) readPredictionData(_in, conf.getProfile(), sf, commonWindow);
}
}
private void readPredictionData(IBitStream _in, Profile profile, SampleFrequency sf, boolean commonWindow) throws AACException {
if (AAC_MAIN == profile) {
if(icPredict==null) icPredict = new ICPrediction();
icPredict.decode(_in, maxSFB, sf);
} else if (AAC_LTP == profile) {
if(ltpData1Present = _in.readBool()) {
if(ltPredict1==null) ltPredict1 = new LTPrediction(frameLength);
ltPredict1.decode(_in, this, profile);
}
if(commonWindow) {
if(ltpData2Present = _in.readBool()) {
if(ltPredict2==null) ltPredict2 = new LTPrediction(frameLength);
ltPredict2.decode(_in, this, profile);
}
}
} else if(ER_AAC_LTP == profile) {
if(!commonWindow) {
if(ltpData1Present = _in.readBool()) {
if(ltPredict1==null) ltPredict1 = new LTPrediction(frameLength);
ltPredict1.decode(_in, this, profile);
}
}
} else {
throw new AACException("unexpected profile for LTP: "+profile);
}
}
/* =========== gets ============ */
public int getMaxSFB() {
return maxSFB;
}
public int getSWBCount() {
return swbCount;
}
public int[] getSWBOffsets() {
return swbOffsets;
}
public int getSWBOffsetMax() {
return swbOffsets[swbCount];
}
public int getWindowCount() {
return windowCount;
}
public int getWindowGroupCount() {
return windowGroupCount;
}
public int getWindowGroupLength(int g) {
return windowGroupLength[g];
}
public WindowSequence getWindowSequence() {
return windowSequence;
}
public boolean isEightShortFrame() {
return windowSequence.equals(WindowSequence.EIGHT_SHORT_SEQUENCE);
}
public int getWindowShape(int index) {
return windowShape[index];
}
public boolean isICPredictionPresent() {
return predictionDataPresent;
}
public ICPrediction getICPrediction() {
return icPredict;
}
public boolean isLTPrediction1Present() {
return ltpData1Present;
}
public LTPrediction getLTPrediction1() {
return ltPredict1;
}
public boolean isLTPrediction2Present() {
return ltpData2Present;
}
public LTPrediction getLTPrediction2() {
return ltPredict2;
}
public void unsetPredictionSFB(int sfb) {
if(predictionDataPresent) icPredict.setPredictionUnused(sfb);
if(ltpData1Present) ltPredict1.setPredictionUnused(sfb);
if(ltpData2Present) ltPredict2.setPredictionUnused(sfb);
}
public void setData(ICSInfo info) {
windowSequence = WindowSequence.valueOf(info.windowSequence.name());
windowShape[PREVIOUS] = windowShape[CURRENT];
windowShape[CURRENT] = info.windowShape[CURRENT];
maxSFB = info.maxSFB;
predictionDataPresent = info.predictionDataPresent;
if(predictionDataPresent) icPredict = info.icPredict;
ltpData1Present = info.ltpData1Present;
if(ltpData1Present) {
ltPredict1.copy(info.ltPredict1);
ltPredict2.copy(info.ltPredict2);
}
windowCount = info.windowCount;
windowGroupCount = info.windowGroupCount;
windowGroupLength = Platform.copyOfInt(info.windowGroupLength, info.windowGroupLength.length);
swbCount = info.swbCount;
swbOffsets = Platform.copyOfInt(info.swbOffsets, info.swbOffsets.length);
}
}