//a律 段落的分界線 (1111 1111)F
static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
0x1FF, 0x3FF, 0x7FF, 0xFFF};
//查找段位置,分為8個段
static short search(short val,short *table, short size)
{
short i;
for (i = 0; i < size; i++) {
if (val <= *table++)
return (i);
}
return (size);
}
//a侓編碼 編碼後為數值8位,其分佈為 |極值(7)|段落(654)|段值(3210)|
unsigned char Snack_Lin2Alaw(short pcm_val) /* 2's complement (16-bit range) */
{
short mask;
short seg; //段落位置
unsigned char aval; //a律的段值
pcm_val = pcm_val >> 3;
//求極性
if (pcm_val >= 0) {
mask = 0xD5; /* sign (7th) bit = 1 */
} else {
mask = 0x55; /* sign bit = 0 */
pcm_val = -pcm_val - 1;
}
//查找所在段落
seg = search(pcm_val, seg_aend, 8);
/* Combine the sign, segment, and quantization bits. */
if (seg >= 8) /* out of range, return maximum value. */
return (unsigned char) (0x7F ^ mask);
//段佔3位、極性佔1位,所以向左移4位,得段值
aval = (unsigned char) seg << SEG_SHIFT; //define SEG_SHIFT (4)
if (seg < 2)//seg為1或0時
aval |= (pcm_val >> 1) & QUANT_MASK; //#define QUANT_MASK (0xf)
else
aval |= (pcm_val >> seg) & QUANT_MASK;
return (aval ^ mask);
}
//a侓解碼
short Snack_Alaw2Lin(unsigned char a_val)
{
short t;
short seg;//段位置
a_val ^= 0x55; //求異或
t = (a_val & QUANT_MASK) << 4; // 得向左移四位的段值
//段位置
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;//#define SEG_MASK (0x70)
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= (seg - 1);
}
return ((a_val & SIGN_BIT) ? t : -t);
}