G711 a律算法代碼解析

//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);

}

你可能感兴趣的:(算法,table,search)