net.sourceforge.jaad.aac.tools.ICPrediction 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.tools;
import org.jcodec.common.logging.Logger;
import net.sourceforge.jaad.aac.AACException;
import net.sourceforge.jaad.aac.SampleFrequency;
import net.sourceforge.jaad.aac.syntax.IBitStream;
import net.sourceforge.jaad.aac.syntax.ICSInfo;
import net.sourceforge.jaad.aac.syntax.ICStream;
/**
* 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.
*
* Intra-channel prediction used in profile Main
* @author in-somnia
*/
public class ICPrediction {
private static final float SF_SCALE = 1.0f/-1024.0f;
private static final float INV_SF_SCALE = 1.0f/SF_SCALE;
private static final int MAX_PREDICTORS = 672;
private static final float A = 0.953125f; //61.0 / 64
private static final float ALPHA = 0.90625f; //29.0 / 32
private boolean predictorReset;
private int predictorResetGroup;
private boolean[] predictionUsed;
private PredictorState[] states;
private static final class PredictorState {
float cor0 = 0.0f;
float cor1 = 0.0f;
float var0 = 0.0f;
float var1 = 0.0f;
float r0 = 1.0f;
float r1 = 1.0f;
}
public ICPrediction() {
states = new PredictorState[MAX_PREDICTORS];
resetAllPredictors();
}
public void decode(IBitStream _in, int maxSFB, SampleFrequency sf) throws AACException {
final int predictorCount = sf.getPredictorCount();
if(predictorReset = _in.readBool()) predictorResetGroup = _in.readBits(5);
final int maxPredSFB = sf.getMaximalPredictionSFB();
final int length = Math.min(maxSFB, maxPredSFB);
predictionUsed = new boolean[length];
for(int sfb = 0; sfb1 ? cor0*even(A/var0) : 0;
final float k2 = var1>1 ? cor1*even(A/var1) : 0;
final float pv = round(k1*r0+k2*r1);
if(output) data[off] += pv*SF_SCALE;
final float e0 = (data[off]*INV_SF_SCALE);
final float e1 = e0-k1*r0;
state.cor1 = trunc(ALPHA*cor1+r1*e1);
state.var1 = trunc(ALPHA*var1+0.5f*(r1*r1+e1*e1));
state.cor0 = trunc(ALPHA*cor0+r0*e0);
state.var0 = trunc(ALPHA*var0+0.5f*(r0*r0+e0*e0));
state.r1 = trunc(A*(r0-k1*e0));
state.r0 = trunc(A*e0);
}
private float round(float pf) {
return Float.intBitsToFloat((Float.floatToIntBits(pf)+0x00008000)&0xFFFF0000);
}
private float even(float pf) {
int i = Float.floatToIntBits(pf);
i = (i+0x00007FFF+(i&0x00010000>>16))&0xFFFF0000;
return Float.intBitsToFloat(i);
}
private float trunc(float pf) {
return Float.intBitsToFloat(Float.floatToIntBits(pf)&0xFFFF0000);
}
}