PCM音頻數據格式介紹

http://blog.csdn.net/ljxt523/article/details/52068241

1. What is PCM?

PCM(Pulse-code-modulation)是模擬信號以固定的採樣頻率轉換成數字信號後的表現形式。

Sample Rate : 
採樣頻率單位爲:Hz。採樣頻率越高,音頻質量越好,佔用空間也越大。

Sign : 
音頻數據是否是有符號的。通常情況下都是有符號的。若是將有符號的數據當做無符號的數據來處理將會使聲音聽來很刺

Sample Size : 
表示每一個採樣數據的大小。通常該值爲16-bit。

Byte Ordering : 
字節序指的是little-endian還是big-endian。表示音頻數據的存儲字節序。通常均爲little-endian。

Number of Channels : 
標識音頻是單聲道(mono,1 channel)還是立體聲(stereo,2 channels)。

通過以上五個數據我們就可以描述一個PCM數據,播放一個PCM數據需要的就是以上五個數據。

2. What does a PCM stream look like?

單聲道

+------+------+------+------+------+------+------+------+------+
|  500 |  300 | -100 | -20  | -300 |  900 | -200 |  -50 |  250 |      
+------+------+------+------+------+------+------+------+------+
  • 1
  • 2
  • 3

每個整數佔據2個字節(16-bit),9個採樣也就是18字節的數據。每個採樣的整數大小最小爲 -32768,最大爲 32768 。根據採樣數據的位置和值畫一個圖的話,就會得到像播放器上那樣的波浪形圖。

我們可以像下面僞代碼示例這樣將數據讀入一個C語言數組 :

FILE *pcmfile
int16_t *pcmdata;
pcmfile = fopen(your pcm data file);
pcmdata = malloc(size of the file);
fread(pcmdata, sizeof(int16_t), size of file / sizeof(int16_t), pcmfile);  
  • 1
  • 2
  • 3
  • 4
  • 5

如果我們將這些數據送入聲卡,我們就可以聽到聲音。當然我們需要告訴聲卡這些數據的採樣率。若我們告知聲卡的採樣率大於數據本身的採樣率,那麼這些數據的播放速度會高於其原始的速度。就是快放的功能。

立體聲

 +----------+----------+---------+----------+---------+----------+---------+----------+----------+
 |  LFrame1 |  RFrame1 | LFrame2 | RFrame2  | LFrame3 |  RFrame3 | LFrame4 |  RFrame4 |  LFrame5 |      
 +----------+----------+---------+----------+---------+----------+---------+----------+----------+
  • 1
  • 2
  • 3

每一個frame是一個16-bit的採樣點。左右聲道的數據交叉存放。

3. Basic Audio Effects – Volume Control

現在讓我們來看一下一些真實的波形圖。最簡單的就是正弦波了。 
這裏寫圖片描述

我們將波形的振幅擴大五倍,圖形如下: 
這裏寫圖片描述

所以如果要增加PCM數據的音量,只需要將每一個採樣的數據乘以一個係數就行了。如果我們的PCM數據有2048個字節,則包含了1024個採樣。我們用如下的僞代碼來擴大音量 :

int16_t pcm[1024] = read in some pcm data;
for (ctr = 0; ctr < 1024; ctr++) {
    pcm[ctr] *= 2;
}
  • 1
  • 2
  • 3
  • 4

音量控制就是這麼簡單,但是要注意兩點

  1. 若採樣點的數據乘以擴大系數之後的值 小於 -32768 或 大於 32768 ,則此處採樣的數值只能取 -32768 或 32768
 int16_t pcm[1024] = read in some pcm data;
 int32_t pcmval;
 for (ctr = 0; ctr < 1024; ctr++) {
     pcmval = pcm[ctr] * 2;
     if (pcmval < 32767 && pcmval > -32768) {
         pcm[ctr] = pcmval
     } else if (pcmval > 32767) {
         pcm[ctr] = 32767;
     } else if (pcmval < -32768) {
         pcm[ctr] = -32768;
     }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  1. 我們將採樣點的數據乘以2並不代表將聲音的音量擴大了兩倍,事實上也的確如此。聲音音量的增益係數與音量的關係如圖: 
    這裏寫圖片描述

以上內容翻譯自:http://www.ypass.net/blog/2010/01/pcm-audio-part-3-basic-audio-effects-volume-control/

4. How to change PCM Sample Rate

根據定義,Sample Rate表示每秒鐘的採樣個數,所以若是要改變音頻的採樣頻率,我們只需要對採樣點做適當的丟棄或者複製就可以。

比如:原始音頻爲opus編碼,單聲道,採樣率爲48kHz,採樣點大小爲16-bit。如何得到編碼爲speex,採樣率爲16kHz,採樣大小爲16-bit的音頻? 
我們需要以下幾步:

  1. 將opus解碼爲PCM格式數據(叫做PCM1),此時的PCM1的採樣率爲48kHz
  2. 將PCM1的數據中第 3*n(n爲從0開始的自然數) 個位置的採樣點,丟棄3*n+1 和3*n+2位置的採樣點。得到PCM2,此時的PCM2採樣率爲48kHz / 3 = 16kHz
  3. 將PCM2編碼爲speex數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章