Audio Unit是一個音頻處理插件。它是為應(yīng)用程序添加復(fù)雜的音頻操作和處理的底層的API。本文主要認(rèn)識Audio Unit的原理和簡單使用
主要內(nèi)容:
- 音頻單元
- Audio Unit使用
- audio processing graph
- 回調(diào)函數(shù)
1. 認(rèn)識
Audio Unit是一個音頻處理插件。它是為應(yīng)用程序添加復(fù)雜的音頻操作和處理的底層的API予权。所有的音頻技術(shù)都是構(gòu)建在這個框架之上的盈电。支持混合映跟、均衡岸蜗、格式轉(zhuǎn)換,用于錄制莹弊、回放、離線渲染和實(shí)時對話的實(shí)時輸入輸出涡尘,流入VoIP(互聯(lián)網(wǎng)協(xié)議語言)忍弛。
功能介紹:
- 具有低延時的實(shí)時I/O,1)如VoIP(互聯(lián)網(wǎng)語音協(xié)議)應(yīng)用程序
- 合成聲音考抄,進(jìn)行回放细疚,例如音樂游戲或合成樂器
- 一些特殊的功能,比如回聲消除川梅,均衡疯兼、混音
- 處理鏈架構(gòu),可將音頻處理模塊組裝到靈活的網(wǎng)絡(luò)中贫途,
優(yōu)勢:
- 出色的響應(yīng)能力:音頻單元渲染的回調(diào)函數(shù)中使用的是實(shí)時優(yōu)先線程吧彪,所以響應(yīng)能力非常出色
- 動態(tài)重新配置:音頻處理圖的API允許我們以線程安全的方式動態(tài)組裝,重新配置和重新排列復(fù)雜的音頻處理鏈丢早,同時處理音頻
音頻單元的生命周期:
- 運(yùn)行時姨裸,獲取對動態(tài)可鏈接庫的引用
- 實(shí)例化音頻單元
- 配置音頻單元
- 初始化音頻單元以使用
- 操作音頻單元
- 取消分配音頻單元
2. 音頻單元
Audio Unit都是有音頻單元組成的秧倾,這里先認(rèn)識音頻單元。
2.1 分類
共有七個音頻單元傀缩,分為四大類那先。
- Effect Unit
- 效果單元,也就是iPod均衡器扑毡,對音頻數(shù)據(jù)進(jìn)行音效處理
- Mixing Unit
- 混音器單元胃榕,可以將不同的音頻混合到一起輸出
- 3D Minxer Unit
- 可以實(shí)現(xiàn)3D混音效果功能,是構(gòu)建OpenAL的基礎(chǔ)瞄摊,一般實(shí)現(xiàn)3D混音都是使用OpenAL
- MutilChannel Minxer Unit
- 實(shí)現(xiàn)多通道混音效果
- 為任意數(shù)量的多通道或立體聲流提供立體聲輸出
- I/O Unit
- Remote I/O 遠(yuǎn)程I/O單元
- 連接輸入輸出硬件設(shè)備的
- voice-processing I/O Unit語音處理I/O單元
- 對語音進(jìn)行處理勋又,比如可以進(jìn)行回聲消除,提供自動增益校正换帜,語音處理質(zhì)量調(diào)整和靜音楔壤。
- Generic Output Unit 通用輸出單元
- 這個輸出不連接設(shè)備,在處理鏈中直接發(fā)到應(yīng)用程序中惯驼,一般用來進(jìn)行離線的音頻操作
- Remote I/O 遠(yuǎn)程I/O單元
- Format conversion Unit
- 格式轉(zhuǎn)換組件蹲嚣,使用在Remote I/O Unit中,將硬件的音頻格式轉(zhuǎn)換成應(yīng)用程序的音頻格式
2.2 組件的基本特征
說明:
- I/O音頻單元包含輸入音頻組件和輸出音頻組件
- 包括輸入輸出scope祟牲,包括輸入輸出element
3. 簡單使用
在iOS中提供了兩種API隙畜,都可以進(jìn)行操作,一種是直接操作Audio Unit说贝,一種是操作Audio Processing Graph(在下文講解)
Audio Unit是在Audio Processing Graph的上下文環(huán)境中工作的
過程示例:
3.1 創(chuàng)建音頻組件描述
說明:
- 它是用來創(chuàng)建不同類型的音頻組件的
- 音頻組件描述中的參數(shù)可以在官網(wǎng)中查找
3.2 創(chuàng)建音頻單元
說明:
- 初始化音頻組件
- 定義音頻組件描述
- 獲取音頻組件的引用
- 實(shí)例化音頻組件
3.3 設(shè)置音頻單元的屬性
給音頻組件設(shè)置scope议惰、element設(shè)置屬性,比如音頻流的格式乡恕,比如回調(diào)函數(shù)設(shè)置等言询。
屬性是一個鍵值對,鍵是系統(tǒng)已經(jīng)定義好的數(shù)值傲宜,值是相應(yīng)的特定類型
常用方法:
- AudioUnitGetPropertyInfo运杭,檢查屬性是否可用
- AudioUnitGetProperty,得到該屬性
- AudioUnitSetProperty函卒,設(shè)置屬性
- AudioUnitAddPropertyListener辆憔,增加監(jiān)聽
- AudioUnitRemovePropertyListnerWithUserData,移除監(jiān)聽
[圖片上傳失敗...(image-dfb5d9-1661917557622)]
說明:
- 這里表示給scope的element設(shè)置了一個流格式屬性报嵌,屬性的值是&audioFormat
- AudioUnitSetPropety一次只能設(shè)置一個屬性
- 設(shè)置屬性可以設(shè)置給scope虱咧,也可以設(shè)置給element
指定音頻單元的部件:
音頻單元是由scope和element組成的,所以想要操作音頻單元沪蓬,需要指定標(biāo)識符
說明:
- scope
- kAudioUnitScope_Global :1)作用于整個音頻單元彤钟,不作用音頻流;2)只有一個element0元素
- kAudioUnitScope_Input和kAudioUnitScope_Output:作用在輸入輸出scope的元素稱為bus跷叉,總線
- element
- element是作用在scope的逸雹,是嵌套在scope的編程上下文
- 關(guān)系
- 屬性可以作用于element营搅,也可以作用于scope
- 一個scope可以有多個element,同一個element可以存在于多個scope
注意:
千萬千萬要注意的一點(diǎn)是:這里是通過element是否是輸入還是輸出來決定這個I/O單元是用來輸入還是輸出的梆砸,而不是通過scope來決定的转质。
3.4 設(shè)置音頻單元的參數(shù)
參數(shù)是用戶可調(diào)節(jié)的設(shè)置,可以在音頻單元正在產(chǎn)生音頻時改變的參數(shù)帖世。
參數(shù)也是一個鍵值對休蟹,key是系統(tǒng)已經(jīng)定義好的數(shù)值,value也是數(shù)值
常用方法:
- AudioUnitGetParameter得到參數(shù)
- AudioUnitSetParameter設(shè)置參數(shù)
4. audio processing graph
音頻處理圖可以用來構(gòu)建和管理音頻單元處理鏈日矫,它可以使用多個音頻單元赂弓,和實(shí)現(xiàn)多個渲染回調(diào)函數(shù),允許我們創(chuàng)建幾乎任何我們能想象的音頻處理解決方案哪轿。
特點(diǎn):
- 線程安全
- 我們重新配置處理圖時盈魁,音頻處理圖的API會將配置的音頻單元添加到稍后要執(zhí)行的更改列表中,當(dāng)指定完所有的更改集后窃诉,就可以請求Graph配置他們了杨耙,這樣就線程安全了。
- 音頻處理圖總是會有一個完整的I/O單元
- 能夠動態(tài)的重新分配處理鏈
- 可以安全的插入AUNode
- 可以在播放音頻時交換不同的渲染回調(diào)函數(shù)
AUNode的認(rèn)識:
- 音頻處理圖是管理AUNode的飘痛,AUNode是鏈的節(jié)點(diǎn)珊膜,作為音頻單元的代理
- 它可以看做是音頻單元,但是如果要設(shè)置音頻單元宣脉,還必須直接配置音頻單元车柠,AUNode本身是不可以配置的
簡單過程:
- 將node增加到Graph中
- 直接配置由node配置的音頻單元
- 互聯(lián)node
代碼實(shí)現(xiàn):
互聯(lián)Node的常用方法:
- 添加或者刪除音頻單元node(AUGraphAddNode, AUGraphRemoveNode)
- 添加或者刪除node之間的連接(AUGraphConnectNodeInput, AUGraphDisconnectNodeInput)
- 將渲染回調(diào)函數(shù)連接到音頻單元的input bus(AUGraphSetNodeInputCallback)
5. 回調(diào)函數(shù)
5.1 音頻流數(shù)據(jù)的獲取
音頻流程圖:
說明:
- 灰色箭頭是調(diào)用函數(shù)的方向
- 橙色箭頭是函數(shù)返回的音頻數(shù)據(jù)的方向
- 初始的音頻數(shù)據(jù)是音頻幀(frame)
- 函數(shù)回調(diào)執(zhí)行完返回的音頻數(shù)據(jù)是切片(slice)
過程詳解:
- AUGraphStart函數(shù)去獲取音頻時,首先會直接在輸出element的緩沖區(qū)中找音頻數(shù)據(jù)
- 如果有脖旱,則直接輸出堪遂,如果沒有則調(diào)用連接到輸入的回調(diào)函數(shù)介蛉,也就是它會調(diào)用這個綁定輸入的函數(shù)
- 此時進(jìn)入到均衡器組件萌庆,獲取數(shù)據(jù),發(fā)現(xiàn)也沒有币旧,就再調(diào)用輸入的回調(diào)函數(shù)
- 此時就從應(yīng)用內(nèi)部獲取到音頻幀
- 拿到音頻幀后就一步一步的執(zhí)行回調(diào)函數(shù)并返回音頻數(shù)據(jù)践险,也就是切片(slice)
5.2 回調(diào)函數(shù)代碼實(shí)現(xiàn)
注釋已足夠詳細(xì)
注意:
- 千萬要注意,回調(diào)函數(shù)必須遵守嚴(yán)格的性能要求
- 回調(diào)函數(shù)是異步執(zhí)行的吹菱,如果這個函數(shù)執(zhí)行耗時太長巍虫,下一個函數(shù)已經(jīng)到達(dá),這個函數(shù)尚未完成執(zhí)行鳍刷,那么就會導(dǎo)致聲音產(chǎn)生間隙
參考文檔: