Android音訊系統之音訊基礎
轉載請註明:LXS, http://blog.csdn.net/uiop78uiop78/article/details/8787779
對於一部嵌入式裝置來說,除了若干基礎功能外(比如手機通話、簡訊),最重要的可能就是多媒體了——那麼一個最簡單的問題,什麼是多媒體呢?
這個術語對應的英文單詞是“Multi-Media”,直譯過來就是多媒體。名稱就很好地解釋了它的含義,我們引用Wikipedia上對其的詳細定義: |
Multimedia is media and content that uses a combination of differentcontent forms. This contrasts with media that use only rudimentary computerdisplays such as text-only or traditional forms of printed or hand-producedmaterial. Multimedia includes a combination of text, audio, still images,animation, video, or interactivity content forms.
換句話說,多媒體是各種形式的媒體(比如文字、音訊、視訊、圖片、動畫等等)的組合。可以說,它是一款產品能否在眾多“同質化”嚴重的市場上脫穎而出的關鍵。另外,由於不同的產品在音訊處理、視訊解碼等晶片方面或多或少都存在差異,原生態的Android系統不可能覆蓋市面上的所有硬體方案,所以這部分功能的移植與二次開發就成了裝置研發中的重頭戲——當然,Android系統在設計之初就充分考慮到了這點,它提供了一整套靈活的多媒體解決方案,以應對廠商的定製化需求。
對於應用開發人員來說,最熟悉最常用的就是MediaPlayer和MediaRecorder,而深藏在這兩個類之間的實現細節卻鮮有人知。這也是Android的一大優點——高度封裝,讓各類開發人員可以把精力放在自己“需要做的事情上”,各司其職,細化分工,從而極大的提高了產品的開發效率。
不過,這種封裝也同時帶來了一些代價。比如系統異常龐大,各種類定義、C++庫、Java封裝等等讓人目不暇接,這給我們剖析多媒體系統帶來了不少障礙。為此,我們特別選取其中的音訊實現(其中大部分又以音訊回放為主),通過有重點、深入的分析音訊系統的實現,來為大家學習Android多媒體系統開啟一個缺口。
本章的內容編排是由下而上的,即從最底層的基礎知識、框架實現講起,再逐步擴充套件延伸到上層應用
· 音訊的基礎知識
理解音訊的一些基礎知識,對於我們分析整個音訊系統是大有裨益的。它可以讓我們從實現的層面去思考,音訊系統的目的是什麼,然後才是怎麼樣去完成這個目的
· AudioFlinger、AudioPolicyService和AudioTrack/AudioRecorder
拋開MediaPlayer、MediaRecorder這些與應用開發直接關聯的部分,整個音訊系統的核心就是由這三者構建而成的。其中前兩個都是System Service,駐留在mediaserver程序中,不斷地處理AudioTrack/AudioRecorder的請求。音訊的回放和錄製從大的流程上看都是相似的,所以我們側重於對AudioTrack的分析
· 音訊的資料流
資料流處理是音訊系統管理的一大重點和難點,至少有如下幾點是需要充分考慮的:
Ø 如何決定音訊流的路徑
通常一臺裝置會有多種音訊裝置,而且同一時間內系統也很可能會播放多種音訊,我們需要將這些音訊流與對應的裝置建立關聯,並做好全域性管理
Ø 如何保證音訊流以有效的速度傳輸到音訊裝置
顯然,資料太快或者太慢都會是缺陷
Ø 跨程序的資料傳遞
舉個例子,從Apk應用程式建立一個MediaPlayer,到音訊真正從裝置中回放出來,這個過程涉及到多個程序間的通訊,如何在這些程序間做好資料傳遞,也是我們所關心的
· 音訊系統的上層建築
在理解了音訊系統的實現核心後,我們再從上層應用的角度來思考,相信會有不一樣的收穫
從物理學的角度來說,聲波是機械波的一種。
機械波(MechanicalWave)是由機械振盪產生的,它的傳播需要介質的支援。它有如下特點:
l 介質本身並不會隨著機械波不斷地前進
比如我們抖動一條繩子產生的繩波,繩子上的某個點只是在一定範圍內做上下運動,沒有因為波的傳遞而脫離繩子。因而機械波是能量的傳遞,而不是質量的傳遞
l 在不同的介質中,傳播速度是不一樣的
那麼,作為機械波的一種,聲音有哪些重要屬性呢?
l 響度(Loudness)
響度就是人類可以感知到的各種聲音的大小,也就是音量。響度與聲波的振幅有直接關係——理論上振幅越大,響度也就越大
l 音調(Pitch)
我們常說某人唱高音很好,或者低音很棒,這就是音調。音調與聲音的頻率有關係——當聲音的頻率越大時,人耳所感知到的音調就越高,否則就越低
l 音色(Quality)
同一種樂器,使用不同的材質來製作,所表現出來的音色效果是不一樣的,這是由物體本身的結構特性所決定的——它直接影響了聲音的音色屬性。同樣的道理,不同的演唱者因為他們的發聲部位有差異,所以才造就了更種嗓音特色的音樂才子
聲音的這幾個屬性,是所有音訊效果處理的基礎。任何對音訊的調整都將反應到這些屬性上,在我們分析原始碼時可以結合起來思考。
上面的多媒體定義還從側面反映出一個結論,即Multi-Media並不是專門為計算機而生的——只不過後者的出現極大地推動了它的發展。那麼和傳統的多媒體相比,計算機領域的多媒體系統,會有哪些區別呢?
一個很顯然的問題是,我們如何將各種媒體源數字化呢?比如,早期的音訊資訊是儲存在錄音帶中的,以模擬訊號的形式儲存。而到了計算機時代,這些音訊資料必須通過一定的處理手段才可能儲存到裝置中,這是我們在數字化時代會遇到的一個常見問題。下面這個圖很好地描述了音訊從錄製到播放的一系列操作流程:
圖 13‑1 音訊的錄製、儲存和回放
引用自http://en.wikipedia.org/wiki/File:A-D-A_Flow.svg
錄製過程:
· 首先,音訊採集裝置(比如Microphone)捕獲聲音資訊,初始資料是模擬訊號
· 模擬訊號通過模-數轉換器(ADC)處理成計算機能接受的二進位制資料
· 上一步得到的資料根據需求進行必要的渲染處理,比如音效調整、過濾等等
· 處理後的音訊資料理論上已經可以儲存到計算機裝置中了,比如硬碟、USB裝置等等。不過由於這時的音訊資料體積相對龐大,不利於儲存和傳輸,通常還會對其進行壓縮處理。比如我們常見的mp3音樂,實際上就是對原始資料採用相應的壓縮演算法後得到的。壓縮過程根據取樣率、位深等因素的不同,最終得到的音訊檔案可能會有一定程度的失真
另外,音視訊的編解碼既可以由純軟體完成,也同樣可以藉助於專門的硬體晶片來完成
回放過程:
回放過程總體上是錄製過程的逆向操作。
l 從儲存裝置中取出相關檔案,並根據錄製過程採用的編碼方式進行相應的解碼
l 音訊系統為這一播放例項選定最終匹配的音訊回放裝置
l 解碼後的資料經過音訊系統設計的路徑傳輸
l 音訊資料訊號通過數模轉換器(DAC)變換成模擬訊號
l 模擬訊號經過回放裝置,還原出原始聲音
本章著重講解的是音訊“回放過程”。
前面我們說過,數字音訊系統需要將聲波波形訊號通過ADC轉換成計算機支援的二進位制,進而儲存成音訊檔案,這一過程叫做音訊取樣(Audio Sampling)。音訊取樣是眾多數字訊號處理的一種,它們的基本原理都是類似的(比如視訊的取樣和音訊取樣本質上也沒有太大區別)。
可想而知,取樣(Sampling)的核心是把連續的模擬訊號轉換成離散的數字訊號。它涉及到如下幾點:
l 樣本(Sample)
這是我們進行取樣的初始資料,比如一段連續的聲音波形
l 取樣器(Sampler)
取樣器是將樣本轉換成終態訊號的關鍵。它可以是一個子系統,也可以指一個操作過程,甚至是一個演算法,取決於不同的訊號處理場景。理想的取樣器要求儘可能不產生訊號失真
l 量化(Quantization)
取樣後的值還需要通過量化,也就是將連續值近似為某個範圍內有限多個離散值的處理過程。因為原始資料是模擬的連續訊號,而數字訊號則是離散的,它的表達範圍是有限的,所以量化是必不可少的一個步驟
l 編碼(Coding)
計算機的世界裡,所有數值都是用二進位制表示的,因而我們還需要把量化值進行二進位制編碼。這一步通常與量化同時進行
整個流程如下圖所示:
圖 13‑2 PCM流程
PCM(Pulse-code modulation)俗稱脈衝編碼調製,是將模擬訊號數字化的一種經典方式,得到了非常廣泛的應用。比如數字音訊在計算機、DVD以及數字電話等系統中的標準格式採用的就是PCM。它的基本原理就是我們上面的幾個流程,即對原始模擬訊號進行抽樣、量化和編碼,從而產生PCM流。另外,我們可以調整PCM的以下屬性來達到不同的取樣需求:
l 取樣速率(Sampling Rate)
在將連續訊號轉化成離散訊號時,就涉及到取樣週期的選擇。如果取樣週期太長,雖然檔案大小得到控制,但取樣後得到的資訊很可能無法準確表達原始資訊;反之,如果取樣的頻率過快,則最終產生的資料量會大幅增加,這兩種情況都是我們不願意看到的,因而需要根據實際情況來選擇合適的取樣速率。
由於人耳所能辨識的聲音範圍是20-20KHZ,所以人們一般都選用44.1KHZ(CD)、48KHZ或者96KHZ來做為取樣速率
l 取樣深度(Bit Depth)
我們知道量化(Quantization)是將連續值近似為某個範圍內有限多個離散值的處理過程。那麼這個範圍的寬度以及可用離散值的數量會直接影響到音訊取樣的準確性,這就是取樣深度的意義
圖 13‑3 採用4-bit深度的PCM,引自Wikipedia
比如上圖是一個採用4位深度進行量化得到的PCM。因為4bit最多隻能表達16個數值(0-15),所以圖中最終量化後的數值依次為7、9、11、12、13、14、15等等。這樣的結果顯然是相對粗糙的,存在一定程度的失真。當位深越大,所能表達的數值範圍越廣,上圖中縱座標的劃分也就越細緻,從而使得量化的值越接近原始資料。
由Harry Nyquist和Claude Shannon總結出來的取樣規律,為我們選擇合適的取樣頻率提供了理論依據。這個規律又被稱為“Nyquist sampling theorem”或者“The sampling theorem”,中文通常譯為“奈奎斯特取樣理論”。它的中心思想是:
“當對被取樣的模擬訊號進行還原時,其最高頻率只有取樣頻率的一半”。
換句話說,如果我們要完整重構原始的模擬訊號,則取樣頻率就必須是它的兩倍以上。比如人的聲音範圍是20-20kHZ,那麼選擇的取樣頻率就應該在40kHZ左右,數值太小則聲音將產生失真現象,而數值太大也無法明顯提升人耳所能感知的音質。
我們在日常生活中會經常聽到單聲道、雙聲道這些專業詞語,那麼它們代表什麼意思呢?
一個聲道(AudioChannel),簡單來講就代表了一種獨立的音訊訊號,所以雙聲道理論上就是兩種獨立音訊訊號的混合。具體而言,如果我們在錄製聲音時在不同空間位置放置兩套採集裝置(或者一套裝置多個採集頭),就可以錄製兩個聲道的音訊資料了。後期對採集到的聲音進行回放時,通過與錄製時相同數量的外放揚聲器來分別播放各聲道的音訊,就可以儘可能還原出錄製現場的真實聲音了。
聲道的數量發展經歷了幾個重要階段,分別是:
l Monaural (單聲道)
早期的音訊錄製是單聲道的,它只記錄一種音源,所以在處理上相對簡單。播放時理論上也只要一個揚聲器就可以了——即便有多個揚聲器,它們的訊號源也是一樣的,起不到很好的效果
l Stereophonic(立體聲)
之所以稱為立體聲,是因為人們可以感受到聲音所產生的空間感。大自然中的聲音就是立體的,比如辦公室裡鍵盤敲擊聲,馬路上汽車鳴笛,人們的說話聲等等。那麼這些聲音為什麼會產生立體感呢?
我們知道,當音源發聲後(比如你右前方有人在講話),音訊訊號將分別先後到達人類的雙耳。在這個場景中,是先傳遞到右耳然後左耳,並且右邊的聲音比左邊稍強。這種細微的差別通過大腦處理後,我們就可以判斷出聲源的方位了。
這個原理現在被應用到了多種場合。在音樂會的錄製現場,如果我們只使用單聲道採集,那麼後期回放時所有的音樂器材都會從一個點出來;反之,如果能把現場各方位的聲音單獨記錄下來,並在播放時模擬當時的場景,那麼就可以營造出音樂會的逼真氛圍。
為了加深大家的理解,我們特別從某雙聲道音訊檔案中提取出它的波形:
圖 13‑4 雙聲道音訊檔案
順便以這個圖為例子再說一下音訊的取樣頻率。我們把上圖進行放大,如下所示:
圖 13‑5 取樣頻率例項
圖上共有三個取樣點,時間間隔是從4:26.790863到4:26.790908左右,也就是說在大約0.000045秒的時間裡採集了兩個點,因而取樣頻率就是:
1/(0.000045/2)=44kHZ,這和此音訊檔案所標記的取樣率是一致的
l 4.1 Surround Sound(4.1環繞立體聲)
隨著技術的發展和人們認知的提高,單純的雙聲道已不能滿足需求了,於是更多的聲道數逐漸成為主流,其中被廣泛採用的就有四聲道環繞立體聲。
其中的“4”代表了四個音源,位置分別是前左(Front-Left)、前右(Front-Right)、後左(Rear-Left)、後右(Rear-Right)。而小數點後面的1,則代表了一個低音喇叭(Subwoofer),專門用於加強低頻訊號效果
l 5.1 Surround Sound(5.1環繞立體聲)
相信大家都聽過杜比數字技術,這是眾多5.1環繞聲中的典型代表。另外還有比如DTS、SDDS等都屬於5.1技術。5.1相對於4.1多了一個聲道,位置排列分別是前左、前右、中置(Center Channel)和兩個Surround Channel,外加一個低音喇叭。
根據ITU(InternationalTelecommunication Union)的建議,5.1環繞技術各揚聲器位置圖如下所示:
圖 13‑6 ITU釋出的5.1環繞技術推薦方點陣圖
即:
l 各揚聲器和聽者距離是一致的,因而組成一個圓形
l 角度分佈:前左和前右分別是+22.5/-22.5度(看電影時),以及+30/-30度(聽音樂時);中置總是為0度;後面的兩個環繞器分別為+110/-110度
估計知道這個定律的人比較少,它是音訊系統中計算聲音大小的一個重要依據。從嚴格意義上講,它並不只適用於聲音感知,而是人體各種感觀(聽覺、視覺、觸覺)與刺激物理量之間的一條綜合規律。其中心思想用公式表達就是:
△I/I=C
其中△I表示差別閾值,I是原先的刺激量,而C則是常量。換句話說,就是能引起感觀變化的刺激差別量與原先的刺激量比值是固定的。這樣子說可能比較抽象,我們舉個例子來說。
場合1. 去商店買一瓶水,原本2塊錢的東西賣到了5塊錢
場合2. 買一輛賓士車,原先價格是一百萬,現在漲了3塊錢
這兩種場景下,前後的價格雖然都是相差3元,但對我們造成的主觀感受是有很大不同的。顯然在第一種情況下,我們會覺得很貴而可能選擇不買;而後者則對我們基本不會產生任何影響。這是因為引起感觀變化的刺激量並不單單取決於前後變化量的絕對差值,同時也與原來的刺激量有很大關係。對於特定的場合,上述公式中的C值是固定的。比如有的人覺得2塊錢的東西賣3元就是貴了,有的人則能接受2塊錢的東西賣4塊,對於不同的人C值是會有差異的。
這就是德國心理物理學家ErnstHeinrich Weber發現的規律,後來的學生GustavFechner把這一發現系統地用公式表達出來,就是上述公式所表達的韋伯定律。
後來,Fechner在此基礎上又做了改進。他提出刺激量和感知是呈對數關係的,即當刺激強度以幾何級數增長時,感知強度則以算術級數增加。這就是Weber–Fechner law,如下公式所示:
S = C log R
那麼這對音訊系統有什麼指導意義呢?
我們知道,系統音量是可調的,比如分為0-20個等級。這些等級又分別對應不同的輸出電平值,那麼我們如何確定每一個等級下應該設定的具體電平值呢?你可能會想到平均分配。沒錯,這的確是一種方法,只不過按照這樣的演算法所輸出的音訊效果在使用者聽來並不是最佳的,因為聲音的變化不連續。
一個更好的方案就是遵循Weber–Fechnerlaw,而採用對數的方法。在Android系統中,這一部分計算具體的實現程式碼在audiosystem.cpp檔案中,大家有興趣的話可以自行閱讀了解下。
前面小節我們分析了音訊取樣的基本過程,它將連續的聲音波形轉換成為若干範圍內的離散數值,從而將音訊資料用二進位制的形式在計算機系統中表示。不過音訊的處理並沒有結束,我們通常還需要對上述過程產生的資料進行格式轉化,然後才最終儲存到裝置中。
要特別注意檔案格式(FileFormat)和檔案編碼器(Codec)的區別。編碼器負責將原始資料進行一定的前期處理,比如壓縮演算法以減小體積,然後才以某種特定的檔案格式進行儲存。Codec和File Format不一定是一對一的關係,比如常見的AVI就支援多種音訊和視訊編碼方式。本小節所講述的以檔案格式為主。
我們把數字音訊格式分為以下幾種:
l 不壓縮的格式(UnCompressed Audio Format)
比如前面所提到的PCM資料,就是取樣後得到的未經壓縮的資料。PCM資料在Windows和Mac系統上通常分別以wav和aiff字尾進行儲存。可想而知,這樣的檔案大小是比較可觀的
l 無失真壓縮格式(Lossless Compressed Audio Format)
這種壓縮的前提是不破壞音訊資訊,也就是說後期可以完整還原出原始資料。同時它在一定程度上可以減小檔案體積。比如FLAC、APE(Monkey’sAudio)、WV(WavPack)、m4a(Apple Lossless)等等
l 有失真壓縮格式(Lossy Compressed Audio Format)
無失真壓縮技術能減小的檔案體積相對有限,因而在滿足一定音質要求的情況下,我們還可以進行有失真壓縮。其中最為人熟知的當然是mp3格式,另外還有iTunes上使用的AAC,這些格式通常可以指定壓縮的比率——比率越大,檔案體積越小,但效果也越差
至於採用哪一種格式,通常要視具體的使用場景而定。