/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This 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 2.1 of * the License, or (at your option) any later version. * * This software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.restcomm.media.codec.ilbc; /** * * @author oifa yulian */ public class BasicFunctions { public static short abs(short var1) { if(var1==Short.MIN_VALUE) return Short.MAX_VALUE; else if(var1<0) return (short)-var1; return (short)var1; } public static short getSize(int var1) throws ArithmeticException { short count; if ((0xFFFF0000 & var1)!=0) count = 16; else count = 0; if ((0x0000FF00 & (var1 >> count))!=0) count += 8; if ((0x000000F0 & (var1 >> count))!=0) count += 4; if ((0x0000000C & (var1 >> count))!=0) count += 2; if ((0x00000002 & (var1 >> count))!=0) count += 1; if ((0x00000001 & (var1 >> count))!=0) count += 1; return count; } public static short norm(int var1) throws ArithmeticException { short count=0; int currValue=var1; if (currValue <= 0) currValue ^= 0xFFFFFFFF; if ((0xFFFF8000 & currValue)==0) count = 16; else count = 0; if ((0xFF800000 & (currValue << count))==0) count += 8; if ((0xF8000000 & (currValue << count))==0) count += 4; if ((0xE0000000 & (currValue << count))==0) count += 2; if ((0xC0000000 & (currValue << count))==0) count += 1; return count; } public static int div(int num, short hi,short low) { short temp1, temp2, numHi, numLow; int temp,tempL,tempShift,approx; if(hi!=0) approx=0x1FFFFFFF/hi; else approx=Integer.MAX_VALUE; tempL=hi*approx; tempL=tempL << 1; temp=tempL; tempL=low*approx; tempL=tempL >> 15; tempL=tempL<<1; temp += tempL; temp = Integer.MAX_VALUE - temp; temp1 = (short)(temp>>16); tempShift=temp1<<16; temp2 = (short)((temp - tempShift)>>1); tempL=(temp1*approx); temp=tempL; tempL=temp2*approx; tempL=tempL>> 15; temp+=tempL; temp = temp << 1; temp1 = (short)(temp>>16); tempShift=temp1<<16; temp2 = (short)((temp - tempShift)>>1); numHi = (short)(num>>16); tempShift=numHi<<16; numLow = (short)((num - tempShift)>>1); tempL=numHi*temp1; temp=tempL; tempL=numHi*temp2; tempL=tempL>> 15; temp+=tempL; tempL=numLow*temp1; tempL=(tempL) >> 15; temp+= tempL; temp = temp<<3; return temp; } //MaxAbsValue public static short getMaxAbsValue(short[] input,int inputIndex,int length) { short currValue=0; int i = inputIndex; int total = inputIndex + length; for(;i<total;i++) if(input[i]>0 && input[i]>currValue) currValue=input[i]; else if(input[i]<0 && (0-input[i])>currValue) currValue=(short)(0-input[i]); return currValue; } //DotProductWithScale public static int scaleRight(short[] input1,int input1Index,short[] input2,int input2Index,int length,int rightShifts) { int sum=0; for(int n=0;n<length;n++) sum+=((input1[input1Index++]*input2[input2Index++])>>rightShifts); return sum; } public static int scaleLeft(short[] input1,int input1Index,short[] input2,int input2Index,int length,int leftShifts) { int sum=0; for(int n=0;n<length;n++) sum+=((input1[input1Index++]*input2[input2Index++])<<leftShifts); return sum; } //ScaleVectorWithSat public static void scaleVector(short[] input, int inputIndex, short[] output, int outputIndex, short gain,int length,int rightShifts) { int i; int temp; for (i = 0; i < length; i++) { temp = (input[inputIndex++]*gain)>>rightShifts; if(temp>Short.MAX_VALUE) output[outputIndex++] = Short.MAX_VALUE; else if(temp<Short.MIN_VALUE) output[outputIndex++] = Short.MIN_VALUE; else output[outputIndex++]=(short)temp; } } //ElementwiseVectorMult public static void multWithRightShift(short[] output,int outputIndex,short[] input1,int input1Index,short[] input2,int input2Index,int length,int rightShifts) { for(int n=0;n<length;n++) output[outputIndex++]=(short)((input1[input1Index++]*input2[input2Index++])>>rightShifts); } public static void multWithLeftShift(short[] output,int outputIndex,short[] input1,int input1Index,short[] input2,int input2Index,int length,int leftShifts) { for(int n=0;n<length;n++) output[outputIndex++]=(short)((input1[input1Index++]*input2[input2Index++])<<leftShifts); } //ReverseOrderMultArrayElements public static void reverseMultiplyRight(short[] out,int outIndex,short[] in,int inIndex,short[] win,int winIndex,int length,int rightShifts) { for (int n = 0; n < length; n++) out[outIndex++]= (short)((in[inIndex++] * win[winIndex--]) >> rightShifts); } public static void reverseMultiplyLeft(short[] out,int outIndex,short[] in,int inIndex,short[] win,int winIndex,int length,int leftShifts) { for (int n = 0; n < length; n++) out[outIndex++]= (short)((in[inIndex++] * win[winIndex--]) << leftShifts); } //VectorBitShiftW32 public static void bitShiftRight(int[] output,int outputIndex,int[] input,int inputIndex,int length,int rightShifts) { for(int n=0;n<length;n++) output[outputIndex++]=input[inputIndex++]>>rightShifts; } public static void bitShiftLeft(int[] output,int outputIndex,int[] input,int inputIndex,int length,int leftShifts) { for(int n=0;n<length;n++) output[outputIndex++]=input[inputIndex++]<<leftShifts; } //AddVectorsAndShift public static void addWithRightShift(short[] out, int outIndex, short[] in1, int in1Index, short[] in2, int in2Index,int length,int rightShifts) { for (int i = length; i > 0; i--) out[outIndex++] = (short)((in1[in1Index++] + in2[in2Index++]) >> rightShifts); } public static void addWithLeftShift(short[] out, int outIndex, short[] in1, int in1Index, short[] in2, int in2Index,int length,int leftShifts) { for (int i = length; i > 0; i--) out[outIndex++] = (short)((in1[in1Index++] + in2[in2Index++]) << leftShifts); } //AddAffineVectorToVector public static void addAffineVectorToVector(short[] out, int outIndex, short[] in, int inIndex, short gain, int addConstant, short rightShifts, int length) { for (int n = 0; n < length; n++) out[outIndex++] += (short)((in[inIndex++]*gain + addConstant) >> rightShifts); } //BwExpand public static void expand(short[] output,int outputIndex,short[] input,int inputIndex,short[] coeficient,int length) { int temp; output[outputIndex++] = input[inputIndex++]; for (int i = 1; i < length; i++) { /* out[i] = coef[i] * in[i] with rounding. in[] and out[] are in Q12 and coef[] is in Q15 */ output[outputIndex++] = (short)((coeficient[i]*input[inputIndex++]+16384)>>15); } } //WebRtcSpl_MemCpyReversedOrder public static void reverseCopy(short[] dest,int destIndex,short[] source,int sourceIndex,int length) { while(length>0) { dest[destIndex--]=source[sourceIndex++]; length--; } } //FilterMAFastQ12 public static void filterMA(short[] input,int inputIndex,short[] output,int outputIndex,short[] B,int bIndex,int bLength,int length) { int o; int i, j; int temp1,temp2; for (i = 0; i < length; i++) { temp2=inputIndex+i; temp1=bIndex; o = 0; for (j = 0; j < bLength; j++) o += B[temp1++]*input[temp2--]; // If output is higher than 32768, saturate it. Same with negative side // 2^27 = 134217728, which corresponds to 32768 in Q12 // Saturate the output if(o>134215679) o=134215679; else if(o<-134217728) o=-134217728; output[outputIndex++] = (short)((o + 2048) >> 12); } } //FilterARFastQ12 public static void filterAR(short[] input,int inputIndex,short[] output,int outputIndex,short[] coefs,int coefsIndex,int coefsLength,int length) { int i, j; int temp2,temp3; int result=0,sum=0; for (i = 0; i < length; i++) { result=0; sum=0; temp2=outputIndex + i - coefsLength + 1; temp3=coefsIndex + coefsLength - 1; for (j = coefsLength - 1; j > 0; j--) sum += coefs[temp3--] * output[temp2++]; result = coefs[coefsIndex] * input[inputIndex++]; result -= sum; // Saturate and store the output. if(result>134215679) result=134215679; else if(result<-134217728) result=-134217728; output[temp2] = (short)((result + 2048) >> 12); } } }