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

net.sourceforge.jaad.aac.syntax.SyntacticElements 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.ChannelConfiguration.CHANNEL_CONFIG_FIVE;
import static net.sourceforge.jaad.aac.ChannelConfiguration.CHANNEL_CONFIG_FIVE_PLUS_ONE;
import static net.sourceforge.jaad.aac.ChannelConfiguration.CHANNEL_CONFIG_MONO;
import static net.sourceforge.jaad.aac.ChannelConfiguration.CHANNEL_CONFIG_SEVEN_PLUS_ONE;
import static net.sourceforge.jaad.aac.ChannelConfiguration.CHANNEL_CONFIG_STEREO;
import static net.sourceforge.jaad.aac.ChannelConfiguration.CHANNEL_CONFIG_STEREO_PLUS_CENTER;
import static net.sourceforge.jaad.aac.ChannelConfiguration.CHANNEL_CONFIG_STEREO_PLUS_CENTER_PLUS_REAR_MONO;

import java.util.logging.Level;

import org.jcodec.common.logging.Logger;

import net.sourceforge.jaad.aac.AACException;
import net.sourceforge.jaad.aac.ChannelConfiguration;
import net.sourceforge.jaad.aac.DecoderConfig;
import net.sourceforge.jaad.aac.Profile;
import net.sourceforge.jaad.aac.SampleBuffer;
import net.sourceforge.jaad.aac.SampleFrequency;
import net.sourceforge.jaad.aac.filterbank.FilterBank;
import net.sourceforge.jaad.aac.sbr.SBR;
import net.sourceforge.jaad.aac.tools.IS;
import net.sourceforge.jaad.aac.syntax.ICSInfo.LTPrediction;
import net.sourceforge.jaad.aac.tools.MS;

/**
 * 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 SyntacticElements implements SyntaxConstants {

	//global properties
	private DecoderConfig config;
	private boolean sbrPresent, psPresent;
	private int bitsRead;
	//elements
	private PCE pce;
	private final Element[] elements; //SCE, LFE and CPE
	private final CCE[] cces;
	private final DSE[] dses;
	private final FIL[] fils;
	private int curElem, curCCE, curDSE, curFIL;
	private float[][] data;

	public SyntacticElements(DecoderConfig config) {
		this.config = config;

		pce = new PCE();
		elements = new Element[4*MAX_ELEMENTS];
		cces = new CCE[MAX_ELEMENTS];
		dses = new DSE[MAX_ELEMENTS];
		fils = new FIL[MAX_ELEMENTS];

		startNewFrame();
	}
	
	public final void startNewFrame() {
		curElem = 0;
		curCCE = 0;
		curDSE = 0;
		curFIL = 0;
		sbrPresent = false;
		psPresent = false;
		bitsRead = 0;
	}

	public void decode(IBitStream _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.debug("SCE");
						prev = decodeSCE_LFE(_in);
						break;
					case ELEMENT_CPE:
					    Logger.debug("CPE");
						prev = decodeCPE(_in);
						break;
					case ELEMENT_CCE:
					    Logger.debug("CCE");
						decodeCCE(_in);
						prev = null;
						break;
					case ELEMENT_DSE:
					    Logger.debug("DSE");
						decodeDSE(_in);
						prev = null;
						break;
					case ELEMENT_PCE:
					    Logger.debug("PCE");
						decodePCE(_in);
						prev = null;
						break;
					case ELEMENT_FIL:
					    Logger.debug("FIL");
						decodeFIL(_in, prev);
						prev = null;
						break;
				}
			}
			Logger.debug("END");
			content = false;
			prev = null;
		}
		else {
			//error resilient raw data block
			ChannelConfiguration cc = config.getChannelConfiguration();
			if (CHANNEL_CONFIG_MONO == cc) {
                decodeSCE_LFE(_in);
			} else if(CHANNEL_CONFIG_STEREO == cc) {
                decodeCPE(_in);
            } else if(CHANNEL_CONFIG_STEREO_PLUS_CENTER == cc) {
                decodeSCE_LFE(_in);
                decodeCPE(_in);
            } else if(CHANNEL_CONFIG_STEREO_PLUS_CENTER_PLUS_REAR_MONO == cc) {
                decodeSCE_LFE(_in);
                decodeCPE(_in);
                decodeSCE_LFE(_in);
            } else if(CHANNEL_CONFIG_FIVE == cc) {
                decodeSCE_LFE(_in);
                decodeCPE(_in);
                decodeCPE(_in);
            } else if(CHANNEL_CONFIG_FIVE_PLUS_ONE == cc) {
                decodeSCE_LFE(_in);
                decodeCPE(_in);
                decodeCPE(_in);
                decodeSCE_LFE(_in);
            } else if(CHANNEL_CONFIG_SEVEN_PLUS_ONE == cc) {
                decodeSCE_LFE(_in);
                decodeCPE(_in);
                decodeCPE(_in);
                decodeCPE(_in);
                decodeSCE_LFE(_in);
			} else {
                throw new AACException("unsupported channel configuration for error resilience: "+cc);
			}
		}
		_in.byteAlign();

		bitsRead = _in.getPosition()-start;
	}

	private Element decodeSCE_LFE(IBitStream _in) throws AACException {
		if(elements[curElem]==null) elements[curElem] = new SCE_LFE(config.getFrameLength());
		((SCE_LFE) elements[curElem]).decode(_in, config);
		curElem++;
		return elements[curElem-1];
	}

	private Element decodeCPE(IBitStream _in) throws AACException {
		if(elements[curElem]==null) elements[curElem] = new CPE(config.getFrameLength());
		((CPE) elements[curElem]).decode(_in, config);
		curElem++;
		return elements[curElem-1];
	}

	private void decodeCCE(IBitStream _in) throws AACException {
		if(curCCE==MAX_ELEMENTS) throw new AACException("too much CCE elements");
		if(cces[curCCE]==null) cces[curCCE] = new CCE(config.getFrameLength());
		cces[curCCE].decode(_in, config);
		curCCE++;
	}

	private void decodeDSE(IBitStream _in) throws AACException {
		if(curDSE==MAX_ELEMENTS) throw new AACException("too much CCE elements");
		if(dses[curDSE]==null) dses[curDSE] = new DSE();
		dses[curDSE].decode(_in);
		curDSE++;
	}

	private void decodePCE(IBitStream _in) throws AACException {
		pce.decode(_in);
		config.setProfile(pce.getProfile());
		config.setSampleFrequency(pce.getSampleFrequency());
		config.setChannelConfiguration(ChannelConfiguration.forInt(pce.getChannelCount()));
	}

	private void decodeFIL(IBitStream _in, Element prev) throws AACException {
		if(curFIL==MAX_ELEMENTS) throw new AACException("too much FIL elements");
		if(fils[curFIL]==null) fils[curFIL] = new FIL(config.isSBRDownSampled());
		fils[curFIL].decode(_in, prev, config.getSampleFrequency(), config.isSBREnabled(), config.isSmallFrameUsed());
		curFIL++;

		if(prev!=null&&prev.isSBRPresent()) {
			sbrPresent = true;
			if(!psPresent&&prev.getSBR().isPSUsed()) psPresent = true;
		}
	}

	public void process(FilterBank filterBank) throws AACException {
		final Profile profile = config.getProfile();
		final SampleFrequency sf = config.getSampleFrequency();
		//final ChannelConfiguration channels = config.getChannelConfiguration();

		int chs = config.getChannelConfiguration().getChannelCount();
		if(chs==1&&psPresent) chs++;
		final int mult = sbrPresent ? 2 : 1;
		//only reallocate if needed
		if(data==null||chs!=data.length||(mult*config.getFrameLength())!=data[0].length) data = new float[chs][mult*config.getFrameLength()];

		int channel = 0;
		Element e;
		SCE_LFE scelfe;
		CPE cpe;
		for(int i = 0; i>8)&BYTE_MASK);
					b[off+1] = (byte) (s&BYTE_MASK);
				}
				else {
					b[off+1] = (byte) ((s>>8)&BYTE_MASK);
					b[off] = (byte) (s&BYTE_MASK);
				}
			}
		}

		buffer.setData(b, freq, chs, 16, bitsRead);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy