1. 程式人生 > >音訊重取樣的基本(我的學習筆記)

音訊重取樣的基本(我的學習筆記)

Part 1:

先介紹最基本的一些概念:

1、何為音訊:聲音的儲存,儲存形式以及播放;

2、取樣頻率(rate):在一段音訊上取樣的頻率,一般常用的為44.1kHz,音訊最大的頻寬20kHz,人耳能分辨的範圍是20Hz~20kHz;

3、失真:傳輸音訊資料過程中,由於將波音放大的時候造成資料缺失稱之為失真;

4、頻譜:頻率譜密度的簡稱,是頻率的分部曲線;

5、雙聲道:立體聲,如果左右兩個聲道波形一樣,可以人為製造一定的相位差,但差是個固定的,這為假立體聲,只有左右兩個聲道波形完全不一樣時才會形成立體聲;

6、錄單聲道:由於錄音時只有一個話筒,所以建議錄音設定引數channels為1,如果錄製雙聲道波形完全一樣,則會造成浪費硬碟儲存空間;

7、錄立體聲:使用兩隻話筒,通過不同位置進行採集;

8、在消除人聲也就是伴唱模式的時候,由於Bass和鼓的相位較小,所以消聲伴奏要做低頻補償;

Part 2:

PCM音訊資料的存數方式

1、pcm資料按照互相交錯格式儲存:LRLRLRLR...具體會有兩種:從小到大:little endian以及big endian從大到小,一般的wav格式檔案都是按照little endian方式儲存;

2、只有左耳有聲音情況是一個聲道的資料全是0,播放器可以將單聲道渲染為雙聲道,但並不是真正意義上的雙聲道;

3、取樣率跟儲存沒有區別,只有跟在儲存空間大小有關係;

4、音訊資料長度 = 秒數 X 取樣率 X 楨長度 / 8;

5、WAV格式檔案的大小計算公式:基於 44.1khz,16bit取樣精度:Size = 44.1khz * 16bit *2(雙聲道) * time(歌曲時長)

Part 3:

音訊裝置檔案簡介:

音訊程式設計介面實際上就是一組音訊裝置檔案,通過它們可以從音效卡中read/write,並控制音效卡設定聲道等引數;

1、/dev/sndstat:  usage: cat dev/sndstat,彙報當前音效卡狀態,檢測音效卡,不適用於程式中;

2、/dev/dsp:是音效卡用語數字取樣(sampleing)和數字錄音(captrueing)檔案,以只讀方式發開的話是輸入聲音,只寫開啟是輸出聲音。無論是向音效卡寫入還是輸出聲音,裝置都具有預設的格式(format),預設為8rate、1ch、8khz,可以通過ioctl呼叫來改變這些引數值;

3、dev/audio:和2相同,同一個硬體上的不同軟體介面;

4、/dev/mixer:應用程式操作混音器的軟體介面,混音器將多個訊號組成或者疊加,對混音器的程式設計包括如何設定控制增益器的級別,在不同的音源間切換,除了open和close

呼叫,其它操作都是由ioctl呼叫完成的,而且允許多個應用程式同時方位。

5、對音效卡維護的核心緩衝區的修改:

int setting = 0xnnyy  , ioctl(handle,SND_DSP_SETFRAGMENT,&setting);

6、dev/snd/controlC0:用於音效卡控制,如通道選擇、混音、麥克風等控制;

7、dev/snd/midiC0D0:用於播放midi音訊檔案;

8、dev/snd/pcmC0D0c:用語錄音的pcm裝置介面;

9、dev/snd/pcmC0D0p:用語播放的pcm裝置介面;

10、dev/snd/seq:音序器;

11、dec/snd/timer:定時器;

Part4:

1、音訊重取樣分為:取樣的位數、取樣的頻率;

2、聲音音質輸出的質量主要取決於音效卡模擬輸入輸出的品質,這跟CODEC轉換品質有著重大關係;(CO:音訊壓縮,DEC:解壓縮,CODEC:多媒體數字訊號解碼器)

3、SRC:改變訊號的取樣率,低取樣率往高取樣率轉換時就是一個重取樣的過程。

4、取樣位數決定取樣精度,如8bit是256個精度,16bit是64k個精度點。

5、WAV格式檔案的大小計算公式:基於 44.1khz,16bit取樣精度

Size = 44.1khz * 16bit *2(雙聲道) * time(歌曲時長)

6、一般由低位向高位進行重取樣的時候最好是整數倍之間進行重採,否則容易造成失真等情況,例如 20khz往上重取樣的時候可以選擇 44.1、88、、、

如果低版本為24向上取樣可選48、96、、、

Part5:

針對音訊重取樣API,這是我當時從其它網站找的相關開源演算法:

API

speex_resampler_process_int()  單聲道 16bit重取樣
speex_resampler_process_float()  重取樣浮點序列 (沒用過)
speex_resampler_process_interleaved_float()   交叉的多通道浮點資料

demo

  1. sr=16000;//原始取樣率
  2. target_sr=44100;//重取樣後取樣率
  3. resampler = speex_resampler_init(1, sr, target_sr, 10, NULL);//初始化
  4. speex_resampler_skip_zeros(resampler);  
  5. while (1)  
  6. {  
  7.     readed=fread(input,2,1600,fdr);  
  8.     if (readed<=0)  
  9.     {  
  10.         break;  
  11.     }  
  12.     in_len=readed;   
  13.     out_len=6400;//輸出緩衝大小
  14.     speex_resampler_process_int(resampler, 0, input, &in_len,output, &out_len); //output傳入緩衝大小,傳出實際大小
  15.     fwrite(output,2,out_len,fdw);  
  16. }  
  17. speex_resampler_destroy(resampler);