[Voice communications] 聲音的濾波


本系列文章主要是介紹 Web Audio API 的相關知識,以及 web語音通信 中會遇到的一些問題,闡述可能存在錯誤,還請多多斧正!

通過設備獲取音頻流會不可避免的滲入一些雜音,這些雜音可能來自你周邊的環境,也有可能來自錄音設備本身,一些低頻的聲音還好,人耳難以分辨出來,但是那些高頻的白噪聲對音質的影響是特別大的,如我們聽收音機沒有調到正確的頻率上,會聽到吱吱茲茲的刺耳的雜音。這些雜音不僅增大了音頻流信號本身的體積,而且我們的耳朵也不喜歡,所以在傳輸之前必須對音頻做相應的濾波處理。

本文地址:http://www.cnblogs.com/hustskyking/p/webAudio-filter.html,轉載請注明源地址。

P.S:請在較新版的 chrome 火狐 Firefox 中測試。

一、濾波節點

1. 接口介紹

頻率,是單位時間內完成振動的次數,是描述振動物體往復運動頻繁程度的量。一段音頻流中包含了各種頻率,溫和的音樂頻率在一個范圍之內,超過這個范圍的聲音一般就是噪聲,人和人之間的語音交流,聲音也是在一定的頻段之中。

在 AudioContext 中用於濾波的節點叫做 BiquadFilterNode,Biquad 是雙二階的意思,這里涉及到了很多通信中專業詞匯,我們暫時可以不用在意。BiquadFilterType 包含了各種濾波類型:

enum BiquadFilterType {
    "lowpass",
    "highpass",
    "bandpass",
    "lowshelf",
    "highshelf",
    "peaking",
    "notch",
    "allpass"
};

用的比較多的就是 lowpass(低通濾波),highpass(高通濾波),bandpass(帶通濾波)。低通濾波就是過濾某個臨界點的高頻信號,只讓低頻信號通過,高通濾波反之。帶通濾波就是允許某個頻段的信號通過。這個節點的參數比較多:

attribute BiquadFilterType type;
readonly attribute AudioParam frequency; // in Hertz
readonly attribute AudioParam detune; // in Cents
readonly attribute AudioParam Q; // Quality factor
readonly attribute AudioParam gain; // in Decibels

void getFrequencyResponse(Float32Array frequencyHz,
                          Float32Array magResponse,
                          Float32Array phaseResponse);

};

其中幾個參數的取值范圍是:

Q 默認是 1, 取值從 0.0001 到 1000.

gain 默認是 0, 取值從 -40 到 40.

2. 初始化接口

我們可以在初始化的時候將 BiquadFilterType 送進去:

// 初始化為低通濾波
var filter = context.createBiquadFilter("lowpass");

當然,我們也可以通過設置他的 AudioParam 來控制參數:

var filter = context.createBiquadFilter();
// 設置為低通濾波
filter.type = filter.LOWPASS;
// 只允許頻率小於 800Hz 的音頻信號通過
filter.frequency.value = 800;

兩只方式都是一樣的,都好控制。

3. DEMO 測試

簡單點的話,中間只用一個 filter 節點就可以了,使用低通濾波,將頻率設置為 800Hz,可以聽到聲音很悶,聲音不是變小了,而是變悶了~節點之間的連接方式是:

Source -> Filter -> Destination

代碼:

var AudioContext = AudioContext || webkitAudioContext;
var context = new AudioContext;
//創建節點
var audio = new Audio("http://qianduannotes.duapp.com/file/SuperMario.mp3");
audio.loop = true;
var media = context.createMediaElementSource(audio);
var filter = context.createBiquadFilter();
filter.type=filter.LOWPASS;
filter.frequency.value=800;
//連接:media → filter → destination
media.connect(filter);
filter.connect(context.destination);
audio.play();

為了方面查看改變頻率之后波形的變化,我做了一些處理:

Source -> Filter -> Analyser -> Destination

                                             |

                                            +-----> 波形繪制到 Canvas

<canvas id="canvas" width="400" height="300"></canvas><br />
<input type="range" min="0" max="100" id="volume" />
<input type="button" onclick="audio.play()" value="播放" />
<input type="button" onclick="audio.pause()" value="暫停" />
<script type="text/javascript">
var AudioContext=AudioContext||webkitAudioContext;
var context=new AudioContext;
//創建節點
var audio = new Audio("http://qianduannotes.duapp.com/file/SuperMario.mp3");
audio.loop = true;
var media=context.createMediaElementSource(audio);
var filter=context.createBiquadFilter();
var analyser=context.createAnalyser();
//只允許小於800的頻率通過
filter.type=filter.LOWPASS;
filter.frequency.value=800;
//Canvas初始化
var width=canvas.width,height=canvas.height;
var g=canvas.getContext("2d");
g.translate(0.5,height/2+0.5);
//連接:media → filter → analyser → destination
media.connect(filter);
filter.connect(analyser);
analyser.connect(context.destination);
//以fftSize為長度創建一個字節數組作為數據緩沖區
var output=new Uint8Array(analyser.fftSize);
//播放幀
(function callee(e){
  analyser.getByteTimeDomainData(output);
  //將緩沖區的數據繪制到Canvas上
  g.clearRect(-0.5,-height/2-0.5,width,height);
  g.beginPath();
  for(var i=0;i<width;i++)
    g.lineTo(i,height*(output[output.length*i/width|0]/256-0.5));
  g.stroke();
  //請求下一幀
  requestAnimationFrame(callee);
})();
//播放
audio.play();
load = volume.onchange = function(){
    filter.frequency.value = volume.value * volume.value;
}
</script>
DEMO Code

這里頻率的變化是:

filter.frequency.value = volume.value * volume.value;

線性變化可能不太明顯,所以改成了平方變化。

二、小結

濾波在通信中一個重要的意義是減少數據傳輸量,節約頻帶,提高傳送效率,在硬件設備還未跟上語音通信的 web環境中,這個操作是十分有意義的!

本節重點是介紹 BiquadFilterNode 在 AudioContext 環境中的使用,比較簡單。

三、參考資料

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM