G711音頻編碼

原理

PCM是對(duì)模擬的連續(xù)信號(hào)進(jìn)行抽樣。
G711則是對(duì)PCM數(shù)據(jù)進(jìn)行再一次的抽樣。
G711主要是對(duì)16bit的PCM進(jìn)行抽樣,取到PCM的高位數(shù)據(jù),去掉低位的數(shù)據(jù),并且只保留8位。這樣壓縮的比率就達(dá)到了2:1??芍怯袚p壓縮。

這里主要討論G711a.
編碼過程
bit: 0--1--2--3--4--5--6--7--8--9--10--11--12--13--14--15
     0----符號(hào)位s
 *  Linear Input Code   Compressed Code
 *  ---------------------------------------
 *  0000000wxyza            000wxyz
 *  0000001wxyza            001wxyz
 *  000001wxyzab            010wxyz
 *  00001wxyzabc            011wxyz
 *  0001wxyzabcd            100wxyz
 *  001wxyzabcde            101wxyz
 *  01wxyzabcdef            110wxyz
 *  1wxyzabcdefg            111wxyz
接下來的部分就是尋找聲音的強(qiáng)度位。
按上表,共有8個(gè)級(jí)別。
標(biāo)記為seg。
然后取強(qiáng)度位之后的4位作為樣本位wxyz
最終經(jīng)過編碼以后
就變成了:s(取反)+3位強(qiáng)度位+4位樣本位總共8位數(shù)據(jù)。
代碼
//強(qiáng)度表
static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF};
//尋找當(dāng)前的強(qiáng)度位,其實(shí)就是前八位的匹配
/*前八位可能性
0x0000 0000
0x0000 0001      
0x0000 0010   
0x0000 0100  
0x0000 1000
0x0001 0000
0x0010 0000
0x0100 0000
*/
static int search(int val, short    *table, int size)
{
    int i;

    for (i = 0; i < size; i++) {
        if (val <= *table++)
            return (i);
    }
    return (size);
}

//編碼
unsigned char pcm2g711a(int pcm_val)
{
    int     mask;
    int     seg;
    unsigned char   aval;

    if (pcm_val >= 0) { //正數(shù)
        mask = 0xD5;    //0x 1101 0101
    } else {            //負(fù)數(shù)
        mask = 0x55;    //0x 0101 0101
        pcm_val = -pcm_val - 1; //取反減1 0x0000 0001
    }
    //mask作用,符號(hào)位取反,偶數(shù)位取反

    //找到高位對(duì)應(yīng)的數(shù)值表所在位置
    seg = search(pcm_val, seg_end, 8);

    //組合符號(hào)位,高位,和高位樣本位
    if (seg >= 8)       //尋找表里最大,直接返回最大值
        return (0x7F ^ mask);
    else {
        aval = seg << SEG_SHIFT;   //左移4位 取得高位,并且最低四位為0000
        if (seg < 2)               //原值seg為0或者1;
            aval |= (pcm_val >> 1) & QUANT_MASK; //右移四位,取樣本位
        else                       //原值seg為2,3,4,5,6,7
            aval |= (pcm_val >> seg) & QUANT_MASK;//右移seg+3位取樣本位
        return (aval ^ mask);      //高位組合樣本為,并且符號(hào)位取反
    }
}
解碼過程
拿到8位的g711編碼數(shù)據(jù)后
與0x55亦或,還原偶數(shù)位,并取強(qiáng)度位。
取得樣本位.
根據(jù)強(qiáng)度位+還原樣本,放大還原。
通過符號(hào)位的值取反得到pcm數(shù)據(jù)的正負(fù)。

代碼

//解碼
short alaw2pcm(
            unsigned char   a_val)
{
    short t;
    short seg;
    
    a_val ^= 0x55;
    
     //后四位a_val即強(qiáng)度樣本位
    t = (a_val & QUANT_MASK) << 4;//左移放大,對(duì)其強(qiáng)度樣本位
    //強(qiáng)度位
    seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
  
    switch (seg) {
        case 0:      //強(qiáng)度位為0,即0x0000 0000
            t += 8;  //即0x0000 0000 0000 1000+強(qiáng)度樣本位
            break;
        case 1:      //強(qiáng)度位為1,即0x0000 0001
            t += 0x108;//即0x0000 0001 0000 1000+強(qiáng)度樣本位
            break;
        default:     //強(qiáng)度位為2-7
            t += 0x108;//即0x0000 0001 0000 1000+強(qiáng)度樣本位
            t <<= seg - 1; //左移恢復(fù)原本數(shù)量級(jí)
    }
    //符號(hào)位
    return ((a_val & SIGN_BIT) ? t : -t);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言: 記載資料多為網(wǎng)絡(luò)搜集,侵刪。 根據(jù)最近接觸的整機(jī)項(xiàng)目做了一些整機(jī)音頻相關(guān)基礎(chǔ)知識(shí)的總結(jié),如有不足或表述問題...
    Gawain_Knowknow閱讀 8,668評(píng)論 0 4
  • 前言 本篇開始講解在Android平臺(tái)上進(jìn)行的音頻編輯開發(fā),首先需要對(duì)音頻相關(guān)概念有基礎(chǔ)的認(rèn)識(shí)。所以本篇要講解以下...
    Ihesong閱讀 8,047評(píng)論 2 18
  • 概述 PCM 脈沖編碼調(diào)制是Pulse Code Modulation的縮寫。脈沖編碼調(diào)制是數(shù)字通信的編碼方式之一...
    充滿活力的早晨閱讀 34,238評(píng)論 0 19
  • 第一章:AV Foundation入門: 1.1 AV Foundation的含義 AV Foundation是蘋...
    武當(dāng)霍元甲閱讀 1,410評(píng)論 0 2
  • 一、簡(jiǎn)介: 關(guān)于聲音的物理定義: 聲音:是由物體振動(dòng)產(chǎn)生的聲波。是通過介質(zhì)傳播并能被人或動(dòng)物聽覺器官所感知的波動(dòng)現(xiàn)...
    司空123閱讀 1,600評(píng)論 0 1

友情鏈接更多精彩內(nèi)容