📄 mulawencoderutil.java
字号:
package net.sf.fmj.media.codec.audio.ulaw;import net.sf.fmj.utility.UnsignedUtils;/** * Turns 16-bit linear PCM values into 8-bit mu-law bytes. * Adapted from code by Marc Sweetgall at http://www.codeproject.com/csharp/g711audio.asp */public class MuLawEncoderUtil{ public static final int BIAS = 0x84; //aka 132, or 1000 0100 public static final int MAX = 32635; //32767 (max 15-bit integer) minus BIAS /** * Sets whether or not all-zero bytes are encoded as 2 instead. * The pcm values this concerns are in the range [32768,33924] (unsigned). */ public boolean getZeroTrap() { return (pcmToMuLawMap[33000] != 0); } public void setZeroTrap(boolean value) { byte val = (byte)(value ? 2 : 0); for (int i = 32768; i <= 33924; i++) pcmToMuLawMap[i] = val; } /** * An array where the index is the 16-bit PCM input, and the value is the mu-law result. */ private static byte[] pcmToMuLawMap; static { pcmToMuLawMap = new byte[65536]; for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) pcmToMuLawMap[UnsignedUtils.uShortToInt((short) i)] = encode(i); } /** * Encode one mu-law byte from a 16-bit signed integer. Internal use only. * * @param pcm A 16-bit signed pcm value * @return A mu-law encoded byte */ private static byte encode(int pcm) { //Get the sign bit. Shift it for later use without further modification int sign = (pcm & 0x8000) >> 8; //If the number is negative, make it positive (now it's a magnitude) if (sign != 0) pcm = -pcm; //The magnitude must be less than 32635 to avoid overflow if (pcm > MAX) pcm = MAX; //Add 132 to guarantee a 1 in the eight bits after the sign bit pcm += BIAS; /* Finding the "exponent" * Bits: * 1 2 3 4 5 6 7 8 9 A B C D E F G * S 7 6 5 4 3 2 1 0 . . . . . . . * We want to find where the first 1 after the sign bit is. * We take the corresponding value from the second row as the exponent value. * (i.e. if first 1 at position 7 -> exponent = 2) */ int exponent = 7; //Move to the right and decrement exponent until we hit the 1 for (int expMask = 0x4000; (pcm & expMask) == 0; exponent--, expMask >>= 1) { } /* The last part - the "mantissa" * We need to take the four bits after the 1 we just found. * To get it, we shift 0x0f : * 1 2 3 4 5 6 7 8 9 A B C D E F G * S 0 0 0 0 0 1 . . . . . . . . . (meaning exponent is 2) * . . . . . . . . . . . . 1 1 1 1 * We shift it 5 times for an exponent of two, meaning * we will shift our four bits (exponent + 3) bits. * For convenience, we will actually just shift the number, then and with 0x0f. */ int mantissa = (pcm >> (exponent + 3)) & 0x0f; //The mu-law byte bit arrangement is SEEEMMMM (Sign, Exponent, and Mantissa.) byte mulaw = (byte)(sign | exponent << 4 | mantissa); //Last is to flip the bits return (byte)~mulaw; } /** * Encode a pcm value into a mu-law byte * * @param pcm A 16-bit pcm value * @return A mu-law encoded byte */ public static byte muLawEncode(int pcm) { return pcmToMuLawMap[pcm & 0xffff]; } /** * Encode a pcm value into a mu-law byte * * @param pcm A 16-bit pcm value * @return A mu-law encoded byte */ public static byte muLawEncode(short pcm) { return pcmToMuLawMap[UnsignedUtils.uShortToInt(pcm)]; }// /**// * Encode an array of pcm values// * // * @param data An array of 16-bit pcm values// * @return An array of mu-law bytes containing the results// */// public static void muLawEncode(int[] data, byte[] encoded)// {// int size = data.length;// // byte[] encoded = new byte[size];// for (int i = 0; i < size; i++)// encoded[i] = muLawEncode(data[i]);// //return encoded;// }//// /**// * Encode an array of pcm values// * // * @param data`An array of 16-bit pcm values// * @return An array of mu-law bytes containing the results// */// public static void muLawEncode(short[] data, byte[] encoded)// {// int size = data.length;// //byte[] encoded = new byte[size];// for (int i = 0; i < size; i++)// encoded[i] = muLawEncode(data[i]);// //return encoded;// }//// /**// * Encode an array of pcm values// * // * @param data An array of bytes in Little-Endian format// * @return An array of mu-law bytes containing the results// */// public static byte[] muLawEncode(byte[] data)// {// int size = data.length / 2;// byte[] encoded = new byte[size];// for (int i = 0; i < size; i++)// encoded[i] = muLawEncode((data[2 * i + 1] << 8) | data[2 * i]);// return encoded;// } /** * Encode an array of pcm values into a pre-allocated target array * * @param data An array of bytes in Little-Endian format * @param target A pre-allocated array to receive the mu-law bytes. This array must be at least half the size of the source. */ public static void muLawEncodeLittleEndian(byte[] data, int offset, int len, byte[] target) { final int size = len / 2; for (int i = 0; i < size; i++) target[i] = muLawEncode(((data[offset + 2 * i + 1] & 0xff) << 8) | (data[offset + 2 * i] & 0xff)); } public static void muLawEncodeBigEndian(byte[] data, int offset, int len, byte[] target) { final int size = len / 2; for (int i = 0; i < size; i++) target[i] = muLawEncode(((data[offset + 2 * i + 1]) & 0xff) | ((data[offset + 2 * i] & 0xff) << 8)); } public static void muLawEncode(boolean bigEndian, byte[] data, int offset, int len, byte[] target) { if (bigEndian) muLawEncodeBigEndian(data, offset, len, target); else muLawEncodeLittleEndian(data, offset, len, target); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -