/* This file is part of jpcsp. Jpcsp 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 3 of the License, or (at your option) any later version. Jpcsp 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 Jpcsp. If not, see <http://www.gnu.org/licenses/>. */ package jpcsp.media.codec.util; import static java.lang.Math.max; import static java.lang.Math.min; import jpcsp.memory.IMemoryWriter; import jpcsp.memory.MemoryWriter; public class CodecUtils { // FLT_EPSILON the minimum positive number such that 1.0 + FLT_EPSILON != 1.0 public static final float FLT_EPSILON = 1.19209290E-07F; public static final float M_SQRT1_2 = 0.707106781186547524401f; // 1/sqrt(2) public static final float M_PI = (float) Math.PI; public static final float M_SQRT2 = 1.41421356237309504880f; // sqrt(2) public static final int ff_log2_tab[] = { 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }; private static int convertSampleFloatToInt16(float sample) { return min(max((int) (sample * 32768f + 0.5f), -32768), 32767) & 0xFFFF; } public static void writeOutput(float[][] samples, int outputAddr, int numberOfSamples, int decodedChannels, int outputChannels) { IMemoryWriter writer = MemoryWriter.getMemoryWriter(outputAddr, numberOfSamples * 2 * outputChannels, 2); switch (outputChannels) { case 1: for (int i = 0; i < numberOfSamples; i++) { int sample = convertSampleFloatToInt16(samples[0][i]); writer.writeNext(sample); } break; case 2: if (decodedChannels == 1) { // Convert decoded mono into output stereo for (int i = 0; i < numberOfSamples; i++) { int sample = convertSampleFloatToInt16(samples[0][i]); writer.writeNext(sample); writer.writeNext(sample); } } else { for (int i = 0; i < numberOfSamples; i++) { int lsample = convertSampleFloatToInt16(samples[0][i]); int rsample = convertSampleFloatToInt16(samples[1][i]); writer.writeNext(lsample); writer.writeNext(rsample); } } break; } writer.flush(); } public static int avLog2(int n) { if (n == 0) { return 0; } return 31 - Integer.numberOfLeadingZeros(n); } private static final float log2 = (float) Math.log(2.0); public static float log2f(float n) { return (float) Math.log(n) / log2; } public static int lrintf(float n) { return (int) Math.rint(n); } public static float exp2f(float n) { return (float) Math.pow(2.0, n); } public static float sqrtf(float n) { return (float) Math.sqrt(n); } public static float cosf(float n) { return (float) Math.cos(n); } public static float sinf(float n) { return (float) Math.sin(n); } public static float atanf(float n) { return (float) Math.atan(n); } public static float atan2f(float y, float x) { return (float) Math.atan2(y, x); } }