?? alawencoderutil.java
字號(hào):
package net.sf.fmj.media.codec.audio.alaw;import net.sf.fmj.utility.UnsignedUtils;/** * Turns 16-bit linear PCM values into 8-bit A-law bytes. * Adapted from code by Marc Sweetgall at http://www.codeproject.com/csharp/g711audio.asp */public class ALawEncoderUtil{ public static final int MAX = 0x7fff; //maximum that can be held in 15 bits /** * An array where the index is the 16-bit PCM input, and the value is * the a-law result. */ private static byte[] pcmToALawMap; static { pcmToALawMap = new byte[65536]; for (int i = Short.MIN_VALUE; i <= Short.MAX_VALUE; i++) pcmToALawMap[UnsignedUtils.uShortToInt((short) i)] = encode(i); } /** * Encode one a-law byte from a 16-bit signed integer. Internal use only. * * @param pcm A 16-bit signed pcm value * @return A a-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 fit in 15 bits to avoid overflow if (pcm > MAX) pcm = MAX; /* 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 0 0 0 0 0 0 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) * The exponent is 0 if the 1 is not found in bits 2 through 8. * This means the exponent is 0 even if the "first 1" doesn't exist. */ int exponent = 7; //Move to the right and decrement exponent until we hit the 1 or the exponent hits 0 for (int expMask = 0x4000; (pcm & expMask) == 0 && exponent>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 . . . . . . . . . (say that 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. * * NOTE: If the exponent is 0: * 1 2 3 4 5 6 7 8 9 A B C D E F G * S 0 0 0 0 0 0 0 Z Y X W V U T S (we know nothing about bit 9) * . . . . . . . . . . . . 1 1 1 1 * We want to get ZYXW, which means a shift of 4 instead of 3 */ int mantissa = (pcm >> ((exponent == 0) ? 4 : (exponent + 3))) & 0x0f; //The a-law byte bit arrangement is SEEEMMMM (Sign, Exponent, and Mantissa.) byte alaw = (byte)(sign | exponent << 4 | mantissa); //Last is to flip every other bit, and the sign bit (0xD5 = 1101 0101) return (byte)(alaw^0xD5); } /** * Encode a pcm value into a a-law byte * * @param pcm A 16-bit pcm value * @return A a-law encoded byte */ public static byte aLawEncode(int pcm) { return pcmToALawMap[UnsignedUtils.uShortToInt((short) (pcm & 0xffff))]; } /** * Encode a pcm value into a a-law byte * * @param pcm A 16-bit pcm value * @return A a-law encoded byte */ public static byte aLawEncode(short pcm) { return pcmToALawMap[UnsignedUtils.uShortToInt(pcm)]; }// /**// * Encode an array of pcm values// * // * @param data An array of 16-bit pcm values// * @parem encoded An array to be filled with a-law bytes containing the results. must be same size as data.// */// public static void aLawEncode(int[] data, byte[] encoded)// {// int size = data.length;// //byte[] encoded = new byte[size];// for (int i = 0; i < size; i++)// encoded[i] = aLawEncode(data[i]);// //return encoded;// }//// /**// * Encode an array of pcm values// * // * @param data An array of 16-bit pcm values// * @parem encoded An array to be filled with a-law bytes containing the results. must be same size as data.// */// public static void aLawEncode(short[] data, byte[] encoded)// {// int size = data.length;// //byte[] encoded = new byte[size];// for (int i = 0; i < size; i++)// encoded[i] = aLawEncode(data[i]);// //return encoded;// }//// /**// * Encode an array of pcm values// * // * @param data An array of bytes in Little-Endian format// * @return An array of a-law bytes containing the results// */// public static byte[] aLawEncode(byte[] data)// {// int size = data.length / 2;// byte[] encoded = new byte[size];// for (int i = 0; i < size; i++)// encoded[i] = aLawEncode((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 A-law bytes. This array must be at least half the size of the source. */ public static void aLawEncode(boolean bigEndian, byte[] data, int offset, int length, byte[] target) { if (bigEndian) aLawEncodeBigEndian(data, offset, length, target); else aLawEncodeLittleEndian(data, offset, length, target); } public static void aLawEncodeLittleEndian(byte[] data, int offset, int length, byte[] target) { int size = length / 2; for (int i = 0; i < size; i++) target[i] = aLawEncode(((data[offset + 2 * i + 1] & 0xff) << 8) | (data[offset + 2 * i]) & 0xff); } public static void aLawEncodeBigEndian(byte[] data, int offset, int length, byte[] target) { int size = length / 2; for (int i = 0; i < size; i++) target[i] = aLawEncode(((data[offset + 2 * i + 1]) & 0xff) | ((data[offset + 2 * i] & 0xff) << 8)); }}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -