Package net.sourceforge.jaad.aac.tools

Source Code of net.sourceforge.jaad.aac.tools.ICPrediction$PredictorState

/*
*  Copyright (C) 2011 in-somnia
*
*  This file is part of JAAD.
*
*  JAAD is free software; you can redistribute it and/or modify it
*  under the terms of the GNU Lesser General Public License as
*  published by the Free Software Foundation; either version 3 of the
*  License, or (at your option) any later version.
*
*  JAAD is distributed in the hope that it will be useful, but WITHOUT
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
*  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
*  Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library.
*  If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.jaad.aac.tools;

import net.sourceforge.jaad.aac.AACException;
import net.sourceforge.jaad.aac.SampleFrequency;
import net.sourceforge.jaad.aac.syntax.BitStream;
import net.sourceforge.jaad.aac.syntax.Constants;
import net.sourceforge.jaad.aac.syntax.ICSInfo;
import net.sourceforge.jaad.aac.syntax.ICStream;
import java.util.logging.Level;

/**
* 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(BitStream 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; sfb<length; sfb++) {
      predictionUsed[sfb] = in.readBool();
    }
    Constants.LOGGER.log(Level.WARNING, "ICPrediction: maxSFB={0}, maxPredSFB={1}", new int[]{maxSFB, maxPredSFB});
    /*//if maxSFB<maxPredSFB set remaining to false
    for(int sfb = length; sfb<maxPredSFB; sfb++) {
    predictionUsed[sfb] = false;
    }*/
  }

  public void setPredictionUnused(int sfb) {
    predictionUsed[sfb] = false;
  }

  public void process(ICStream ics, float[] data, SampleFrequency sf) {
    final ICSInfo info = ics.getInfo();

    if(info.isEightShortFrame()) resetAllPredictors();
    else {
      final int len = Math.min(sf.getMaximalPredictionSFB(), info.getMaxSFB());
      final int[] swbOffsets = info.getSWBOffsets();
      int k;
      for(int sfb = 0; sfb<len; sfb++) {
        for(k = swbOffsets[sfb]; k<swbOffsets[sfb+1]; k++) {
          predict(data, k, predictionUsed[sfb]);
        }
      }
      if(predictorReset) resetPredictorGroup(predictorResetGroup);
    }
  }

  private void resetPredictState(int index) {
    if(states[index]==null) states[index] = new PredictorState();
    states[index].r0 = 0;
    states[index].r1 = 0;
    states[index].cor0 = 0;
    states[index].cor1 = 0;
    states[index].var0 = 0x3F80;
    states[index].var1 = 0x3F80;
  }

  private void resetAllPredictors() {
    int i;
    for(i = 0; i<states.length; i++) {
      resetPredictState(i);
    }
  }

  private void resetPredictorGroup(int group) {
    int i;
    for(i = group-1; i<states.length; i += 30) {
      resetPredictState(i);
    }
  }

  private void predict(float[] data, int off, boolean output) {
    if(states[off]==null) states[off] = new PredictorState();
    final PredictorState state = states[off];
    final float r0 = state.r0, r1 = state.r1;
    final float cor0 = state.cor0, cor1 = state.cor1;
    final float var0 = state.var0, var1 = state.var1;

    final float k1 = var0>1 ? 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);
  }
}
TOP

Related Classes of net.sourceforge.jaad.aac.tools.ICPrediction$PredictorState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.