/* * 21.04.2004 Original verion. davagin@udm.ru. *----------------------------------------------------------------------- * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *---------------------------------------------------------------------- */ package davaguine.jmac.decoder; import java.util.Arrays; /** * Author: Dmitry Vaguine * Date: 04.03.2004 * Time: 14:51:31 */ public class AntiPredictorExtraHigh3800ToCurrent extends AntiPredictor { private short[] bm = new short[256]; private AntiPredictorExtraHighHelper Helper = new AntiPredictorExtraHighHelper(); private int[] FM = new int[9]; private int[] FP = new int[9]; private short[] IPAdaptFactor = null; private short[] IPShort = null; public void AntiPredict(int[] pInputArray, int[] pOutputArray, int NumberOfElements, int nVersion) { final int nFilterStageElements = (nVersion < 3830) ? 128 : 256; final int nFilterStageShift = (nVersion < 3830) ? 11 : 12; final int nMaxElements = (nVersion < 3830) ? 134 : 262; final int nFirstElement = (nVersion < 3830) ? 128 : 256; final int nStageCShift = (nVersion < 3830) ? 10 : 11; //short frame handling if (NumberOfElements < nMaxElements) { System.arraycopy(pInputArray, 0, pOutputArray, 0, NumberOfElements); return; } //make the first five samples identical in both arrays System.arraycopy(pInputArray, 0, pOutputArray, 0, nFirstElement); //variable declares and initializations Arrays.fill(bm, (short) 0); int m2 = 64, m3 = 115, m4 = 64, m5 = 740, m6 = 0; int p4 = pInputArray[nFirstElement - 1]; int p3 = (pInputArray[nFirstElement - 1] - pInputArray[nFirstElement - 2]) << 1; int p2 = pInputArray[nFirstElement - 1] + ((pInputArray[nFirstElement - 3] - pInputArray[nFirstElement - 2]) << 3); int op = nFirstElement; int ip = nFirstElement; int IPP2 = pInputArray[ip - 2]; int p7 = 2 * pInputArray[ip - 1] - pInputArray[ip - 2]; int opp = pOutputArray[op - 1]; int Original; //undo the initial prediction stuff int q; // loop variable for (q = 1; q < nFirstElement; q++) { pOutputArray[q] += pOutputArray[q - 1]; } //pump the primary loop if (IPAdaptFactor == null || IPAdaptFactor.length < NumberOfElements) IPAdaptFactor = new short[NumberOfElements]; if (IPShort == null || IPShort.length < NumberOfElements) IPShort = new short[NumberOfElements]; for (q = 0; q < nFirstElement; q++) { IPAdaptFactor[q] = (short) (((pInputArray[q] >> 30) & 2) - 1); IPShort[q] = (short) pInputArray[q]; } Arrays.fill(FM, 0); Arrays.fill(FP, 0); for (q = nFirstElement; op < NumberOfElements; op++, ip++, q++) { //CPU load-balancing if (nVersion >= 3830) { int pFP = 8; int pFM = 8; int nDotProduct = 0; FP[0] = pInputArray[ip]; if (FP[0] == 0) { nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM--]; FP[pFP--] = FP[pFP - 1]; } else if (FP[0] > 0) { nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] += ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; } else { nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; nDotProduct += FP[pFP] * FM[pFM]; FM[pFM--] -= ((FP[pFP] >> 30) & 2) - 1; FP[pFP--] = FP[pFP - 1]; } pInputArray[ip] -= nDotProduct >> 9; } Original = pInputArray[ip]; IPShort[q] = (short) pInputArray[ip]; IPAdaptFactor[q] = (short) (((pInputArray[ip] >> 30) & 2) - 1); pInputArray[ip] -= (Helper.ConventionalDotProduct(IPShort, q - nFirstElement, bm, 0, IPAdaptFactor, q - nFirstElement, Original, nFilterStageElements) >> nFilterStageShift); IPShort[q] = (short) pInputArray[ip]; IPAdaptFactor[q] = (short) (((pInputArray[ip] >> 30) & 2) - 1); ///////////////////////////////////////////// pOutputArray[op] = pInputArray[ip] + (((p2 * m2) + (p3 * m3) + (p4 * m4)) >> 11); if (pInputArray[ip] > 0) { m2 -= ((p2 >> 30) & 2) - 1; m3 -= ((p3 >> 28) & 8) - 4; m4 -= ((p4 >> 28) & 8) - 4; } else if (pInputArray[ip] < 0) { m2 += ((p2 >> 30) & 2) - 1; m3 += ((p3 >> 28) & 8) - 4; m4 += ((p4 >> 28) & 8) - 4; } p2 = pOutputArray[op] + ((IPP2 - p4) << 3); p3 = (pOutputArray[op] - p4) << 1; IPP2 = p4; p4 = pOutputArray[op]; ///////////////////////////////////////////// pOutputArray[op] += (((p7 * m5) - (opp * m6)) >> nStageCShift); if (p4 > 0) { m5 -= ((p7 >> 29) & 4) - 2; m6 += ((opp >> 30) & 2) - 1; } else if (p4 < 0) { m5 += ((p7 >> 29) & 4) - 2; m6 -= ((opp >> 30) & 2) - 1; } p7 = 2 * pOutputArray[op] - opp; opp = pOutputArray[op]; ///////////////////////////////////////////// pOutputArray[op] += ((pOutputArray[op - 1] * 31) >> 5); } } }