All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.jaad.aac.syntax.ICSInfo Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy