package net.sourceforge.jaad.aac.syntax;
import java.util.Arrays;
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.MSMask;
/**
* 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 CPE extends Element implements SyntaxConstants {
private MSMask msMask;
private boolean[] msUsed;
private boolean commonWindow;
ICStream icsL, icsR;
CPE(int frameLength) {
super();
msUsed = new boolean[MAX_MS_MASK];
icsL = new ICStream(frameLength);
icsR = new ICStream(frameLength);
}
void decode(IBitStream _in, DecoderConfig conf) throws AACException {
final Profile profile = conf.getProfile();
final SampleFrequency sf = conf.getSampleFrequency();
if(sf.equals(SampleFrequency.SAMPLE_FREQUENCY_NONE)) throw new AACException("invalid sample frequency");
readElementInstanceTag(_in);
commonWindow = _in.readBool();
final ICSInfo info = icsL.getInfo();
if(commonWindow) {
info.decode(_in, conf, commonWindow);
icsR.getInfo().setData(info);
msMask = CPE.msMaskFromInt(_in.readBits(2));
if(msMask.equals(MSMask.TYPE_USED)) {
final int maxSFB = info.getMaxSFB();
final int windowGroupCount = info.getWindowGroupCount();
for(int idx = 0; idx<windowGroupCount*maxSFB; idx++) {
msUsed[idx] = _in.readBool();
}
}
else if(msMask.equals(MSMask.TYPE_ALL_1)) Arrays.fill(msUsed, true);
else if(msMask.equals(MSMask.TYPE_ALL_0)) Arrays.fill(msUsed, false);
else throw new AACException("reserved MS mask type used");
}
else {
msMask = MSMask.TYPE_ALL_0;
Arrays.fill(msUsed, false);
}
if(profile.isErrorResilientProfile()&&(info.isLTPrediction1Present())) {
if(info.ltpData2Present = _in.readBool()) info.getLTPrediction2().decode(_in, info, profile);
}
icsL.decode(_in, commonWindow, conf);
icsR.decode(_in, commonWindow, conf);
}
public ICStream getLeftChannel() {
return icsL;
}
public ICStream getRightChannel() {
return icsR;
}
public MSMask getMSMask() {
return msMask;
}
public boolean isMSUsed(int off) {
return msUsed[off];
}
public boolean isMSMaskPresent() {
return !msMask.equals(MSMask.TYPE_ALL_0);
}
public boolean isCommonWindow() {
return commonWindow;
}
public static MSMask msMaskFromInt(int i) throws AACException {
MSMask[] values = MSMask.values();
if (i >= values.length) {
throw new AACException("unknown MS mask type");
}
return values[i];
}
}