標籤:
1. http://www.leiphone.com/news/201406/record.html
關於手機錄音和降噪那些事
本文作者是科通芯城的何順義工程師。
想必大家都有這樣的經曆:接到朋友從火車站、地鐵、會場、KTV等場合打來的電話,有時候很難聽清楚,有時候卻聽得很清晰。這是為什嗎?
通常我們會認為是對方訊號不穩定,所以通話品質有好有壞。其實不然,這種環境下能否聽清對方講話,主要取決於對方手機錄音和降噪功能的優劣。同時,這也是高端手機和普通手機的一個重要區別。
任何功能的差別,歸根到底,都是硬體和軟體的差別。在本文中,筆者將花較長的篇幅和網友們分享一下手機的錄音、降噪的原理;所需要的硬體、演算法;以及不同的硬體、演算法,在使用體驗上的差別。希望對大家能有些協助。
錄音過程和硬體
首先說一下為什麼要強調手機的錄音功能。
很簡單,手機是用來通話的。通話的過程,首先要把說話的人的聲音錄下來,然後聽者才可以聽得到。所以,錄音功能對於通話,是基礎而重要的。
對於手機的錄音過程,簡單地講,需要經過三個階段,兩個環節。三個環節是:“聲音——類比電訊號——數字電訊號”。兩個環節是:“麥克風”和“ADC(analog digital converter/數字類比轉換器)”。麥克風負責把“聲音”轉化為“類比電訊號”,ADC負責把“類比電訊號”轉化為“數字電訊號”。所以說,麥克風和ADC的品質直接決定錄音功能的品質。
麥克風大家比較熟悉,這裡不再贅述,主要講一下ADC。
如何衡量一個ADC的品質?簡單點講,看兩個參數:採樣速度和量化位元。什麼是採樣速度和量化位元?可以這麼理解,採樣速度代錶速度,而量化位元代表精度。這兩個數值都是越大越好。
那麼,怎麼知道手機中ADC的“採樣速度”和“量化位元”呢?辦法是有的:
先下載一個叫“RecForg”的免費APP,安裝運行之後,找到“設定”菜單,進入後介面如所示▼
中,有兩個紅色方框:“採樣率”和“音頻格式”。這兩個子功能表分別對應ADC的“採樣速度”和“量化位元”。
在筆者手機上,點擊“採樣率”進入之後的介面如下▼
可以看出,有三個檔位是灰色不可選的:12kHz、24kHz、 48kHz。而其它所有檔位都可以選擇。這說明筆者手機ADC的“採樣速率”有5個檔位,最高為44kHz。同時,筆者也測試過朋友的小米2,發現其最高的採樣速率是48kHz。這說明小米2使用的ADC要比筆者手機的ADC高一個等級。
在“設定”菜單介面,點擊“音頻格式”子功能表進入之後,會看到▼
說明,筆者手機的ADC的“量化位元”是16位。
很簡單吧?需要說明的是,筆者發現APP“RecForg”只在android平台手機上可以找到,而在IOS裡是沒有的。如果大家想查看Iphone的ADC的參數,可以嘗試找一些類似的錄音軟體,碰碰運氣,說不準會有發現呢。
降噪原理和演算法
在“錄音過程和硬體”部分,講到了錄音需要的硬體,以及硬體效能對於錄音品質的影響。
如果在安靜的環境中,軟體對於通話的影響並不大。然而,手機是移動通訊裝置,通話情境不確定,很可能是在嘈雜環境中的。在這種情況下,降噪演算法對於通話品質就至關重要了。
降噪是怎麼回事?簡單點說,就是通過演算法,從接收到的聲音中分離出人聲和雜訊,把人聲加強,把雜訊抑制,從而提高通話品質。道理很簡單,但在具體實現上,演算法非常複雜,各手機公司一般都不會自己做降噪演算法,而是採用相關專業公司的方案。
說到降噪,不得不提audience公司。這是一家專門從事移動通訊音頻技術的全球領導公司,通俗點說,就是做音頻降噪演算法的公司。蘋果、三星、HTC、Google、LG、華為、夏普、魅族、小米等都是audience的客戶,如果要列舉採用audience晶片的機型,將會是一張非常長的名單。
那麼,不同的降噪演算法,體現使用者體驗上,會有什麼區別呢?
我們可以在嘈雜的環境中,可以進行兩種實驗。(一)、在嘈雜環境中,使用“免提通話”,對方可以聽很清楚的條件下,說話者和手機的最大距離是多遠?(二)、在嘈雜環境中,手機可以語音辨識的最大距離是多遠?筆者測試過一些高端手機和普通手機,結果差別還蠻大。大家如果有興趣,也可以試一試。
上面是從體驗方面來說降噪效能。那麼除了主觀感受,是否可以有一個客觀的、直觀的展現呢?答案也是肯定的。見▼
是iphone4s和小米2播放通道的頻率響應曲線。可以明顯地看出,iphone4s在低頻(<80Hz)和高頻段(>1.4Hz)都做了相應的降噪處理,只保留和人聲頻段。而小米2隻在高頻段有降噪處理。這也說明和iphone4s相比,小米在一些細節上還是有一定提升空間。
2. http://blog.163.com/l1_jun/blog/static/143863882013517105217611/
IOS、安卓IM語音交談開發初探部分心得——本地音頻處理篇(下)原文連結:http://cvito.net/index.php/archives/869
前文書咱們說到IOS下如何錄製一個wav格式的音頻,然而現在的情況確實安卓不支援wav格式,於是有看官說了,你個二百五,就不能選個安卓支援的格式錄製麼,我很負責任的說,蘋果和Google掐架,苦的就是我們這幫苦逼的技術人員。。。安卓的格式蘋果全不支援,看好是全不,不是全部,反過來蘋果的格式,安卓也不慣著。。。。
當然上有政策下有對策是萬年不變的真理,Ios與安卓的音頻互連是難不倒我們偉大的程式員的,而目前解決這個問題方案有很多種但大致以下3種方式,且聽我細細道來。
第一種方案對於伺服器負荷較大,不論是安卓端亦或是IOS端都將音頻傳輸到伺服器,通過伺服器進行轉換再進行轉寄。這種做法可以不受系統限制,但是資訊量較大時對伺服器負荷較大,對伺服器端的要求很高。據傳聞,就是採用這種方式進行的語音IM互動
第二種方案是不論IOS端還是安卓端都統一使用相同的第三方音頻庫進行編解碼處理,然後再進行網路傳輸,優點是可供選擇的音頻庫非常多,可以根據自己不同的需求選擇各種各樣的音頻格式,但是因為不論是IOS端還是安卓端都需要對其進行i編碼解碼處理,而項目初期並沒有設計這方面的需求所以如果雙端都進行修改修改量實在太大。同樣據傳聞,同為語音IM的成熟案例微米就是依靠Speex的三方開源庫來完成的,這種格式體積小,能降噪,是目前比較受推崇的方式。
我採用的是第三種方式,amr格式的音頻檔案是安卓系統中預設的錄音檔案,也算是安卓支援的很方便的音頻檔案,IOS系統曾經是支援這種格式的檔案,自4.3以後才取消了對amr的支援(原因應該不需要我多說。。。),可見,amr格式的音頻檔案並非IOS處理不了的,因為有了這樣的概念和潛意識的植入,我就開始一門心思在網路上找尋各種各樣的執行個體以及demo,我要做的就是把問題盡量都解決在IOS端。終於功夫不負有心人,最終讓我得以成功的在IOS端成功的轉換出安卓端可以使用的amr檔案。接下來,我們就說說如何在IOS端完成wav與amr檔案的互轉。
首先推薦給大夥提供一個demo在下面的串連下載。此demo轉載自中國開源社區,本人發自內心的向發行者Jeans大人致以最崇高的敬意。
http://www.oschina.net/code/snippet_562429_12400
demo下載開啟項目後將如下四個源碼檔案以及兩個庫檔案拖入自己的項目,引用AudioToolbox.framework、CoreAudio.framework以及AVFouncation.framework即可完成類庫的匯入
開啟我們匯入的標頭檔就會發現有又大量的struct,而在開啟ARC項目中是禁止使用struct和union的,而我們的項目確實可以開啟ARC的,這裡涉及到一個知識點,之前也在網路上看到有人提問在開啟ARC後改如何使用struct,我也是接觸這個項目之後開始涉及混編才瞭解該如何解決這個問題, 只要將Compile Sources As(設定編譯源)的設定為Ojbective-C++或者將包含到聲名struct和union標頭檔的實作檔案的副檔名改為.mm就可以在項目中使用struct和union了,但是請注意此時你編寫的代碼不再是純粹的Objective-C語言了,而是涉及到Objective-C++,此處涉及到混編的問題,我們再後面還會再講解混編相關的內容,但並不會很多,感興趣的看官可以自己尋找資料。回到原題,如果在匯入檔案後遇到了編譯錯誤,請點擊項目的TARGETS下的Build Settings找到以下編譯設定並按照圖內容修改
注意,如果是建立空項目Compile Sources As的設定在According to File Type(依照檔案類型選擇編譯源)的模式下應該也可以正常編譯,盡量不要設定為Ojbective-C++進行編譯,我是因為項目中含有其他的SDK需要用到所以才如此設定,一旦設定成Ojbective-C++會和我們之後講的網路傳輸篇中所使用的SDK產生一定衝突很那解決。所以此最好保持According to File Type。
檔案正常匯入之後就可以直接使用轉換方法了,和常規的SDK不同,這個庫並非以累的形式封裝的,而是數個功能函數,所以並不需要我們去構造對象,接下來我們說一下轉換時具體用到的方法,雖然這些方法簡單易用,但是我還是願意為大家提供一點便利,所謂幫人到底送佛送到西,下面我每一個方法的名稱、功能、參數說明以及使用樣本貼出以供大家參考~。
哦~對了不要忘記,我們的第一步永遠都是匯入標頭檔
#import “amrFileCodec.h”;
接下來我們開始第一個函數EncodeWAVEFileToAMRFile從函數名稱中就可看出,此方法是將WAV轉換為AMR檔案的,我們先來看一下樣本
參數列表也並不是很複雜4個參數分別問:1.WAV的檔案地址,2.AMR的檔案地址,3.音頻通道數,也就是我們上篇文章中所提到錄製音訊最後一個參數,聲道數量。4.編碼位元,同樣在上一篇文章中我們也已經介紹過不再贅述。
接下來第二個函數,DecodeAMRFileToWAVEFile這個參數與前一個功能正好相反,是從amr轉換為WAV,下面是具體程式碼範例
這個參數可以說較上一個更加簡單,第一個參數是需要一個AMR的檔案地址也就是源,第二個參數則是目標地址也就是一個WAV檔案的地址,簡單的兩個參數就可完成調用了。需要注意的是,此處所使用的地址和之前我們再使用AVFouncation的時候又不同了,它既不是要NSString的字串,也不是NSURL對象而是一個const char的指標,但是這並不是問題,執行個體代碼中所轉換的方法並不是最簡的只是急於示範所以拖拽出來的,希望有心的看官可以自行過濾,過眼不過心是編程大忌。
相對於匯入可以說使用的方法簡單的一塌糊塗,並不需要我們多少功夫,也沒有那麼高深莫測,但是測試還是要下一定功夫的,經過實機檢測IOS下錄製出的WAV轉換為AMR之後放到安卓平台可以正常播放,而安卓錄製的AMR檔案拿到IOS下轉換出WAV一樣可以播放完全沒有任何問題。但是這個方法也是有一定的弊端,音頻轉換的速度較慢,如果是時間較長的音頻檔案轉換起來會有短時間頓卡,但是用來實現語音IM聊天是完全可以滿足的
至此我們本地音頻處理篇的內容全部完結,也算是告一段落,但是我們現在只是在本地機器上實現了正確的音頻轉換以及播放,想要完成語音IM聊天我們還差關鍵的環節就是與伺服器的互動,詳細的內容,我們將在下一篇文章中介紹,盡請關注IOS、安卓IM語音交談開發初探部分心得——非同步Socket傳輸篇
ios音頻降噪/拼接