MuLaw and ALaw
11337 ワード
The mu-law byte bit arrangement is SEEEMMMM (Sign, Exponent, and Mantissa.)
MuLaw
ALaw
//The a-law byte bit arrangement is SEEEMMMM (Sign, Exponent, and Mantissa.)
MuLaw
/// <summary>
/// Encode one mu-law byte from a 16-bit signed integer. Internal use only.
/// </summary>
/// <param name="pcm">A 16-bit signed pcm value</param>
/// <returns>A mu-law encoded byte</returns>
private static byte encode(int pcm)
{
//Get the sign bit. Shift it for later use without further modification
// xxxx xxxx xxxx xxxx
// 1000 0000 0000 0000
// ---------------------
// ?000 0000 0000 0000
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
//MAX = 32635
if (pcm > MAX) pcm = MAX;
//Add 132 to guarantee a 1 in the eight bits after the sign bit
//132 = 1000 0100
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
// 0x4000 = 100 0000 0000 0000
// Sxxx xxxx xxxx xxxx
// 100 0000 0000 0000
// ---------------------
// ?00 0000 0000 0000
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. */
// 0x0f = 1111
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
//~01111111 127
//----------
// 10000000 128
return (byte)~mulaw;
}
//decode
/// <summary>
/// Decode one mu-law byte. For internal use only.
/// </summary>
/// <param name="mulaw">The encoded mu-law byte</param>
/// <returns>A short containing the 16-bit result</returns>
private static short decode(byte mulaw)
{
//Flip all the bits
mulaw = (byte)~mulaw;
//Pull out the value of the sign bit
// xxxx xxxx
// 1000 0000
// -----------
// ?000 0000
int sign = mulaw & 0x80;
//Pull out and shift over the value of the exponent
// xxxx xxxx
// 111 0000
// ----------
// ??? 0000
int exponent = (mulaw & 0x70) >> 4;
//Pull out the four bits of data
// xxxx xxxx
// 1111
// ----------
// ????
int data = mulaw & 0x0f;
//Add on the implicit fifth bit (we know the four data bits followed a one bit)
// xxxx xxxx
// 1 0000
//----------
// x xxxx
data |= 0x10;
/* Add a 1 to the end of the data by shifting over and adding one. Why?
* Mu-law is not a one-to-one function. There is a range of values that all
* map to the same mu-law byte. Adding a one to the end essentially adds a
* "half byte", which means that the decoding will return the value in the
* middle of that range. Otherwise, the mu-law decoding would always be
* less than the original data. */
// x xxxx0
data <<= 1;
// x xxxx1
data += 1;
/* Shift the five bits to where they need to be: left (exponent + 2) places
* Why (exponent + 2) ?
* 1 2 3 4 5 6 7 8 9 A B C D E F G
* . 7 6 5 4 3 2 1 0 . . . . . . . <-- starting bit (based on exponent)
* . . . . . . . . . . 1 x x x x 1 <-- our data
* We need to move the one under the value of the exponent,
* which means it must move (exponent + 2) times
*/
data <<= exponent + 2;
//Remember, we added to the original, so we need to subtract from the final
data -= MuLawEncoder.BIAS;
//If the sign bit is 0, the number is positive. Otherwise, negative.
return (short)(sign == 0 ? data : -data);
}
ALaw
//The a-law byte bit arrangement is SEEEMMMM (Sign, Exponent, and Mantissa.)
/// <summary>
/// Encode one a-law byte from a 16-bit signed integer. Internal use only.
/// </summary>
/// <param name="pcm">A 16-bit signed pcm value</param>
/// <returns>A a-law encoded byte</returns>
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);
}
/// <summary>
/// Decode one a-law byte. For internal use only.
/// </summary>
/// <param name="alaw">The encoded a-law byte</param>
/// <returns>A short containing the 16-bit result</returns>
private static short decode(byte alaw)
{
//Invert every other bit, and the sign bit (0xD5 = 1101 0101)
alaw ^= 0xD5;
//Pull out the value of the sign bit
int sign = alaw & 0x80;
//Pull out and shift over the value of the exponent
int exponent = (alaw & 0x70) >> 4;
//Pull out the four bits of data
int data = alaw & 0x0f;
//Shift the data four bits to the left
data <<= 4;
//Add 8 to put the result in the middle of the range (like adding a half)
data += 8;
//If the exponent is not 0, then we know the four bits followed a 1,
//and can thus add this implicit 1 with 0x100.
if (exponent != 0)
data += 0x100;
/* Shift the bits to where they need to be: left (exponent - 1) places
* Why (exponent - 1) ?
* 1 2 3 4 5 6 7 8 9 A B C D E F G
* . 7 6 5 4 3 2 1 . . . . . . . . <-- starting bit (based on exponent)
* . . . . . . . Z x x x x 1 0 0 0 <-- our data (Z is 0 only when exponent is 0)
* We need to move the one under the value of the exponent,
* which means it must move (exponent - 1) times
* It also means shifting is unnecessary if exponent is 0 or 1.
*/
if (exponent > 1)
data <<= (exponent - 1);
return (short)(sign == 0 ? data : -data);
}