天天看點

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

本文參考網址:

g711編碼原理

量化與采樣

數字音頻信号處理

數字音頻處理概念

數字音頻處理要做的大方向是把我們所聽到的聲音以數字的方式記錄下來,讓計算機進行處理。

先來簡單說說聲音這部分:

此時此刻你所能聽到的動靜就是聲音,,這個聲音是通過我的聲帶震動産生的,你之是以能聽到是因為我的聲帶震動迫使着空氣震動,聲音在空氣中以波的形式傳播,空氣震動迫使你的耳骨膜震動,進而聽到聲音。

怎麼記錄聲音?

既然震動耳骨膜能讓人聽到聲音,那麼我們就用某個物體來模仿我們的耳骨膜來接收聲音。例如:留聲機中的振片就相當于人類的耳骨膜。

我們把振片接收的聲音通過AD變換器轉變為數字信号。

AD變換器(analogue digital) 模拟數字

模拟信号到數字信号分為3部:采樣,量化,編碼

采樣:聲音的模拟信号是一段連續的波形,數字信号是對波形進行采樣得到的(采樣:采集樣本),一個點表示一個樣本,采樣所取得的數值是音頻的模拟電壓值。

量化:用數字化的值來表示電壓,就要把電壓值劃分成若幹等級,每個等級可表示為一個數值,這就是量化。量化簡單的說就是對采樣點進行近似值表示,分得級越多,數字音頻品質就越高。通常電話語音用8位(256級)或CD用16位(65536級)。

編碼:模拟信号轉為數字信号說白了就是将模拟信号進行編碼,将量化值以二進制的方式進行表示叫編碼。

PCM

PCM(pulse code modulation脈沖編碼調制)是把聲音從模拟信号轉成數字信号的一種技術。

也就是A/D變換器。

原理: 按照一個固定的頻率去采樣。是以對pcm來說有兩個重要的名額:采樣頻率和量化精度。

【采樣頻率】:

剛才我們說樣本是從波形中采集到的一個點。一次隻能在波形中采一個樣本。我們為了讓計算機還原波形,必須要在規定時間内進行足夠多次采樣操作才能接近原波形。我們知道,頻率 = 1 / 周期,畫個源波形和采樣波形。如果采樣率為1Hz,那麼周期為1,表示每一秒采一次樣本,如果采樣率是2,那麼周期為0.5,表示每0.5秒采一次,波形就變成這樣,可以推斷出,在規定時間内,采樣頻率越高,聲音還原的效果越好。咱們通信音頻采樣率一般為8000Hz,也就是1秒采8000次樣本。

采樣定理: 用大于信号最高頻率兩倍的頻率,對周期信号進行采樣,可以保證完全重構原始信号。

人的聽力感覺範圍是20~20000Hz,信号最高頻率是20000Hz,是以cd的采樣頻率大于40000Hz就能還原出人耳所能感覺到到的所有聲音,常見的比如44.1kHz,48kHz, 96kHz

之是以會取一個大于40k的采樣頻率比如44.1k、48k甚至更高的96k,可能是因為采樣後需要量化,量化會有誤差,為了縮小量化誤差,要麼提高采樣頻率,要麼增加量化精度。

【量化精度】:

也就是剛才我們說的對電壓值進行分級,一級表示一個數值,用這個數值去近似表示采樣點,一個數值表示一個樣本,量化精度越高,量化值就越接近采樣點,越接近就越準确。

量化分為均勻量化和非均勻量化。

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

由圖可知:均勻量化中,量化間隔均勻劃分,無論電壓信号強弱,每個樣本的絕對誤差都相等,結果導緻振幅較低的地方失真嚴重,不适合弱信号(例如語音信号)。

非均勻量化,弱信号量化間隔密,強信号量化間隔疏。

如果按照非均勻量化,弱信号量化間隔密,能表示弱信号的量化值也就變多了,改善了弱信号失真的情況。

改善弱信号失真的方法有兩種,一種是剛才說的,采用非均勻量化的方式,第二種就是提高量化精度。

同樣的波形在相同的采樣頻率下比較分8位和分16位,明顯是16bit能細化出更多不相同的樣本值。

編碼:

剛才我們說道,把量化值用二進制的方式表示叫編碼。

有些編碼方式不會對原始資料量進行壓縮,是以原生16bitpcm樣本是沒經過壓縮的編碼資料。壓縮是編碼的一種。

資料壓縮分為有損壓縮和無損壓縮,有損壓縮雖說是有損,不影響正常收聽。

壓縮的方式有很多種:

  1. 在一個樣本内部進行壓縮。
  2. 相鄰兩個樣本間取不相同的地方(做差)進行壓縮,是以在播放時,後一個樣本依賴于前一個樣本。
  3. 将樣本以塊來處理,取平均值。

現在介紹第一種壓縮方式——在樣本内部進行壓縮。

g711是一種由國際電信聯盟制定的一套語音壓縮标準,主要用于電話語音通信,而人聲最大頻率一般在3.4kHz,是以隻要以8k的采樣頻率對人聲進行采樣,就可以保證完全還原原始聲音。

g711的内容是将一個13bit或14bit的樣本編碼成一個8bit的樣本。

g711标準主要分兩種壓縮方法:a-law和mu-law,

a-law:将一個13bit的pcm樣本壓縮成一個8bit的pcm樣本。

mu-law:将一個14bit的pcm樣本壓縮成一個8bit的pcm樣本。

【問題】:剛才不是說pcm是16位的麼,怎麼就變成了13bit14bit

【解答】:

13bit14bit取決于你A/D轉換器的量化精度,對13bit精度的量化值進行編碼,得到一個13bit二進制pcm樣本值,也得用2位元組也就是16bit去存,在這種編碼規則下,13位14位和16位的樣本都是用2位元組來存,無法将他們區分出來,是以就看你是讓高13位賦予意義還是讓低13位賦予意義。

對于一個pcm二進制樣本來說,高位代表強信号,低位代表弱信号。我最開始寫代碼取的是高13位,我用強信号去代表整個樣本,結果就導緻了弱信号解析不清楚,音頻品質一般,聲音有點小,感覺像是給你的耳朵蓋上一層棉被聽音樂。于是我就改取了低13位,采取放大弱信号的方式,整體運作出來的音質更好一些。

a-law

a-law采用13折線法編碼,13折線是從“非均勻量化”基點出發,非均勻量化是精分低信号,粗分高信号。alaw編碼的目标是将一個13bit的pcm樣本壓縮成一個8bit樣本.

  1. 假設x/y的最大取值範圍都是-1~+1.
  2. x/y軸分别代表量化級和分段序号(輸入/輸出)。是以13折線法的目的實際上是在給量化級分段,每段用一個固定的序号來表示。
  3. 将x軸不均等分成8段。按照每次1/2取分,分成8個段,7個點。
    g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm
  4. 将y軸均勻分8份
  5. 将x/y軸各段交點連接配接起來

    分成7個點:1/128,1/64,1/32,1/16,1/8,1/4,1/2

    分成8個段:1/128,1/128,1/64,1/32,1/16,1/8,1/4,1/2(x軸每個點之間的間隔)

【由圖可知】:

0~1/128段和1/128~1/64的距離相等(是1/64平分來的),是以這兩段的斜率相同,可以将第一第二段看作一大段,是以實際上是分了7段不同的斜率。

因為取值是±1,是以反向還有一段一樣的圖,因為±1±2斜率相同,是以将其合成一大段,這時整個圖總共有13段斜率不同的折線,這就是13折線法的由來。

x軸的量化我還沒畫完,實際上它是這樣的。當我們在x軸每一段中再均等分16份,這時他就是128級,因為他是8bit,得分到256級為止,我就不在細化了。

可以看到折線的變化越來越平緩,當x值較大時,有大範圍的x都被量化成8,量化精度較低,當x值較小時,折線變化劇烈,量化精度高。

在16bit的pcm中挑出13bit,經過了13折線法,生成了一個8bit的樣本,

看表格第二縱列

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

壓縮後的資料隻有8bit,用char來存放,s是符号位,八段序号對應000~111(8段),abcd是從16bit的pcm中截取的有效樣本。

看表格第一豎列一共有13bit,第一位是符号位,序号位是符号位之後碰到的第一個1之間的位數,包括這個1…序号位最多有7位,這7位從低位往高位數,第一位是1就對應1,第二位是1就對應2,第7位是1就對應7,全是0就對應0.

是以代碼的難點隻有在13位的pcm中找符号位之後的第一個1。(就這麼簡單)

看代碼

關于位運算:

& 與 :同1則1
| 或 :有1則1
~取反:按位取反
^ 亦或:相同為1
<< 左移:×
>> 右移:/
十進制中想要把0010向左移一位
變成0100,是不是要 * 10^1, 
是以十進制的0010 << 2,
就表示0010 * 10^2
同理,二進制的0010 << 1 是0010 × 2的1次方
           

代碼流程:

  1. 取符号位。
  2. 找符号位後第一個1,擷取序号位。将除了符号位以外的12位取出,傳入函數中去找第一個一。
  3. 拼接符号位,序号位,樣本位。
  4. 傳回對偶位二進制位取反。
    g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

問題:負數變正數時為什麼要-1?

解答:我們傳進來的數是有符号數,例如4bit的有符号二進制表示是從0~7, -1~-8。把負數取絕對值變正數之後變成1~8,總體比0~7大1,是以-pcm變正後要-1.

查找第一個1:

【計算式】:

将除符号位外的12位進行與運算

1000 0000 0000 進行與運算,同1則1
,如果與出來的結果為0,那麼表示這一位不是1,
如果與出來的數不為0, 則表示該樣本的序号位是7,
函數傳回所對應的序号.
flag二進制上的1右移一位變成
0100 0000 0000 以同樣的方式進行與,
直到找到第一個1,找不到意味着全是0,傳回0.
           

【記錄式】:

若這12位pcm > 0111 1111 1111(0x7ff),
則表示這12位pcm的最高位是1(1xxx xxxx xxxx),
最高位是1對應的是序号7,傳回7.

如果pcm < 0111 1111 1111, 
讓pcm與0011 1111 1111比較,
如果大于傳回6, 小于的話就将最高位的1變為0
這時我們就能打出個表,從0x1f~0x7ff
           

當序号位 = 0時, pcm要右移一位才能把abcd都放在低4位

否則,序号位 = 幾就右移幾位,目的是将abcd放在低4位

最後就是把符号位,序号位,樣本位放在8bit中該放的位置。

0xd5 = 1101 0101。

這就是alaw算法實作壓縮。

pcma轉pcm代碼

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

mulaw

mu-law:将14bit的pcm樣本變8bit。不均勻量化

比alaw多一位

折線圖我就不細講了。

看表

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

看第二縱列,依然是符号位s,序号位000~111(共8段),有效位abcd

看第一縱列,序号位最長是8. 序号位從低位往高位看,1在第1位代表0, 在第2位代表1,在第八位代表7.

​ 規律:1在第n位代表n - 1

偏移表:

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

代碼流程:

  1. 取符号位
  2. 将除符号位外的13位取出,找第一個一,擷取序号位
  3. 拼接
  4. 全部取反
    g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

和alaw不一樣的地方是mu-law整體會進行一個線性的偏移,

原本mulaw14bit的pcm樣本除去一位符号位外還剩13bit,13bit二進制位有213種狀态 = 8192,關于mulaw的相關文檔上寫着8159是mulaw的最大量化級。

偏移量為33.

是以為了友善計算機進行處理,給所有的樣本都+33

為什麼??!!

這一塊我到現在都不是很懂,有哪個明白的大佬能幫忙解釋一下麼。。。。

pcm += (0x84 >> 2)

這行代碼是從sox源碼中抄的。sox加33為什麼用這麼騷的操作?

直接加不好麼?變成

pcm += 0x21

不是更直接麼?

pcmu轉pcm代碼

g711原理pcm轉alaw,pcm轉ulaw,alaw轉pcm,ulaw轉pcm

調制

編好碼後進行調制,怎麼調制才能播放?

三個條件一個都不能少。

  1. 聲道數:單 / 立體
  2. 樣本位數:一個樣本的二進制位數。4bit、8bit、16bit、32bit
  3. 采樣頻率:表示一秒采集樣本的次數。(一次一個樣本)采樣頻率越高,樣本數量越多,還原的越好。

像平時我們接觸的什麼mp3,wav格式的音頻裡面都記錄着這三條基本資訊,mp3,wav都是音頻資料的裝載容器,資訊記錄在容器的頭部,播放器通過這些資訊才知道要怎麼解析這段音頻資料。

pcm不是按一幀裝一個樣本來打包的,而是按照打包率進行打包,咱們組對音頻的采樣頻率規定為8kHz,1幀有160個樣本。

是以160/8000 = 0.02s的打包率,1s = 1000ms ,打包率 = 20ms,是以1s / 20ms = 50Hz,也就是一秒收50幀。

往常我們播放視訊音樂時出現的xxkb/s是比特率,表示一秒鐘處理的bit數。

比特率 = 樣本位數 * 采樣頻率 * 聲道數

以壓縮後的8位pcm,采樣頻率為8000Hz,一幀有160個樣本例。

一秒采8000個樣本。一個樣本占8bite,是以一秒收8bit * 8000個樣本 * 1個聲道數 = 64kb/s 的比特率。

一幀的播放時間 =

160 / 8000(打包率) * 1000ms

繼續閱讀