net.sourceforge.jaad.aac.syntax.SyntacticElements 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.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);
}
}