如下概念是文中經常使用的詞語,由於其含義通常直接用英文表達, 通常不需中文翻譯,可將其理解爲固定名詞詞組.html
注意每一個element還可能具備input scope與output scope.node
Audio Unit : iOS提供音頻處理插件,支持混合,均衡,格式轉換和實時輸入/輸出,用於錄製,播放,離線渲染和實時對話,例如VoIP(互聯網協議語音).能夠從iOS應用程序動態加載和使用它.編程
Audio Unit一般在稱爲audio processing graph的封閉對象的上下文中工做,如圖所示。在此示例中,您的應用程序經過一個或多個回調函數將音頻發送到graph中的第一個audio unit,並對每一個audio unit進行單獨控制。 最終生成的I / O unit直接輸出給鏈接的硬件.設計模式
audio unit是iOS音頻層面中最底層的編碼層,若是要充分利用它須要對audio unit有更深刻的瞭解.除非你須要實時播放同步的聲音,低延遲的輸入輸出或是一些音頻優化的其餘特性,不然請使用Media Player, AV Foundation, OpenAL, or Audio Toolbox等上層框架.數組
Audio Unit提供了更快,模塊化的音頻處理,同時提供了強大的個性化功能,如立體聲聲像,混音,音量控制和音頻電平測量。若是想充分使用它的功能,必須深刻了解包括音頻數據流格式,回調函數和音頻單元架構等基礎知識。安全
如圖所示,audio unit是iOS中音頻最底層的API,audio unit僅在高性能,專業處理聲音的需求下使用纔有意義.bash
使用場景網絡
功能 | Audio units |
---|---|
Effect | iPod Equalizer |
Mixing | 3D Mixer,Multichannel Mixer |
I/O | Remote I/O, Voice-Processing I/O, Generic Output |
Format conversion | Format Converter |
提供一組預設均衡曲線,如重低音,流行音等等。session
Mixer Units數據結構
I/O Units
Format Converter Unit
一般經過I/O unit間接使用.
iOS有一個用於直接處理audio units的API,另外一個用於處理audio processing graphs,能夠同時使用這兩種API. 然而這兩種API中有一部分功能是相同的,以下:
AudioComponentDescription ioUnitDescription;
ioUnitDescription.componentType = kAudioUnitType_Output;
ioUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
ioUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
ioUnitDescription.componentFlags = 0;
ioUnitDescription.componentFlagsMask = 0;
AudioComponent foundIoUnitReference = AudioComponentFindNext (
NULL,
&ioUnitDescription
);
AudioUnit ioUnitInstance;
AudioComponentInstanceNew (
foundIoUnitReference,
&ioUnitInstance
);
複製代碼
AudioComponentFindNext
:第一個參數設置爲NULL表示使用系統定義的順序查找第一個匹配的audio unit.若是你將上一個使用的audio unit引用傳給該參數,則該函數將繼續尋找下一個與之描述匹配的audio unit.
還可使用audio processing graph API初始化audio unit
// Declare and instantiate an audio processing graph
AUGraph processingGraph;
NewAUGraph (&processingGraph);
// Add an audio unit node to the graph, then instantiate the audio unit
AUNode ioNode;
AUGraphAddNode (
processingGraph,
&ioUnitDescription,
&ioNode
);
AUGraphOpen (processingGraph); // indirectly performs audio unit instantiation
// Obtain a reference to the newly-instantiated I/O unit
AudioUnit ioUnit;
AUGraphNodeInfo (
processingGraph,
ioNode,
NULL,
&ioUnit
);
複製代碼
以下圖,Audio Units由Scopes,Elements組成.
scope: audio unit內部的編程上下文,scope概念有一點抽象,能夠這樣理解,好比input scope表示裏面全部的element都須要一個輸入。output scope 表示裏面全部的element都會輸出到某個地方。至於global scope應該是用來配置一些和輸入輸出概念無關的屬性。
element: 當element是input/output scope的一部分時,它相似於物理音頻設備中的信號總線.所以這兩個術語"element, bus"在audio unit中是一個含義.本文檔在強調信號流時使用「bus」,在強調音頻單元的特定功能方面時使用「element」,例如I / O unit的輸入和輸出element.
上圖展現了audio unit的一種常見架構,其中輸入和輸出上的element數量相同。然而,不一樣的audio unit使用不一樣架構。例如,mixer unit可能具備多個輸入element可是具備單個輸出element。
input , output scopes直接參與經過audio unit移動一個或多個音頻流.audio進入input scope並從output scope離開 。屬性或參數能夠做爲總體應用於input或output scope,例如kAudioUnitProperty_ElementCount.其餘屬性和參數(如enable I / O屬性(kAudioOutputUnitProperty_EnableIO)或volume參數(kMultiChannelMixerParam_Volume))適用於特定scope的element.
注意: 能夠這樣理解scope,scope就是音頻流動的方位,好比從input scope流動到 output scope, 而element是與硬件掛鉤的,好比input element是跟麥克風鏈接的,音頻從input element的input scope流入,從它的output scope流出.
UInt32 busCount = 2;
OSStatus result = AudioUnitSetProperty (
mixerUnit,
kAudioUnitProperty_ElementCount, // the property key
kAudioUnitScope_Input, // the scope to set the property on
0, // the element to set the property on
&busCount, // the property value
sizeof (busCount)
);
複製代碼
用於在I / O unit上啓用或禁用輸入或輸出。默認狀況下,輸出已啓用但輸入已禁用。
配置mixer unit上的輸入elements的數量
爲了指定音頻數據的最大幀數,audio unit應該準備好響應於回調函數調用而產生。對於大多數音頻設備,在大多數狀況下,您必須按照參考文檔中的說明設置此屬性。若是不這樣作,屏幕鎖定時您的音頻將中止。
指定特定audio unit輸入或輸出總線的音頻流數據格式。
大多數屬性只能在audio unit沒有初始化時指定,可是某些特定屬性能夠在audio unit運行時設置,如kAUVoiceIOProperty_MuteOutput
靜音功能.
要測試屬性的可用性,訪問其值以及監視其值的更改,請使用如下函數:
audio unit parameter是用戶能夠在audio unit運行時提交的參數,經過下面的函數實現.
儘管這兩個elements是audio unit的一部分,但你的app應該把它們當作兩個獨立的實體.例如,你能夠根據需求使用kAudioOutputUnitProperty_EnableIO
屬性獨立啓用或禁用每一個element.如上圖,Element 1直接與音頻輸入硬件(麥克風)鏈接,在藍色區域輸入端的鏈接範圍對於開發者是不透明的,開發者能夠在黃色區域,即Element 1輸出端獲取麥克風採集的音頻數據.一樣地,Element 0的輸出端直接與音頻硬件(揚聲器)鏈接,開發者能夠將音頻數據交給Element 0的輸入端,輸出端是不透明的.
實際使用過程當中,咱們常常須要選擇使用哪一個element,使用時咱們常使用它們的編號而不是名稱,input element編號爲1,output elemnet編號爲0.(能夠將input首字母I當作1,ouput首字母O當作0來記憶)
如上圖所示,每一個element都有本身的輸入,輸入範圍.這是爲了更加清楚的描述.例如,在一個同時具有輸入輸出音頻的app中,你能夠收到音頻從input element的 output scope, 發送音頻給output element的input scope.
audio processing graph(AUGraph):基於Core Foundation風格的數據結構,經常使用來管理audio unit處理鏈. graph能夠利用多個audio unit與回調函數,以用來解決任意音頻處理方法。
AUGraph
類型保證了線程安全.例如播放音頻時,容許你添加一個均衡器或者在mixer輸入端更換回調函數.AUGraph
提供了音頻動態配置在iOS平臺.AUNode
: 表明graph上下文中單個的audio unit.使用graph時,咱們經常使用它做爲代理與audio unit交互,而不是直接使用audio unit.當咱們將graph放在一塊兒時,必須使用audio unit的API配置每一個audio unit. 而nodes則不能直接配置audio unit.所以,使用graph必須同時使用這兩套API.
使用AUNode實例對象(使用node表明一個完整的audio processing subgraph)做爲一個複雜graph中的element.在這種狀況下, I/O unit結尾的subgraph必須是Generic Output unit(不能鏈接音頻硬件的I/O unit).
步驟
不管你正在錄製,播放或是同步,每一個audio processing graph都有一個I/0 unit.經過AUGraphStart
與AUGraphStop
能夠開啓或中止音頻流.經過AudioOutputUnitStart
與AudioOutputUnitStop
能夠開啓或中止I/O unit.經過這種方式,graph的I / O單元負責graph中的音頻流。
audio processing graph API保證了線程安全.此API中的某些功能會將一個audio unit添加到稍後要執行的更改列表中.指定完整的更改集後,而後要求graph去實現它們。
如下是audio processing graph API支持的一些常見從新配置及其相關功能:
如下是一個從新配置運行中的audio processing graph.例如,構建一個graph包含Multichannel Mixer unit與Remote I/O unit.用於播放合成兩種輸入源的混音效果.將兩個輸入源的數據送給Mix的input buses.mixer的輸出端鏈接I/OUnit的output element最終將聲音傳給硬件.
在上面這種狀況下,用戶若是想在任一一路流前插入一個均衡器.能夠添加一個iPod EQ unit在從硬件輸入端到mixer輸入端以前.如圖,如下是從新配置的步驟
AUGraphDisconnectNodeInput
斷開mixer unit input 1 的「beats sound」回調。AUGraphAddNode
將其加入到graph.此時,iPod EQ unit已具備實例化對象但未初始化,已經存在於graph中但未參與音頻流.AudioUnitGetProperty
從mixer的輸入端檢索kAudioUnitProperty_StreamFormat
流格式.AudioUnitSetProperty
,一次設置iPod EQ unit’s input流格式,一次設置輸出流格式.AudioUnitInitialize
以分配內存準備使用.這個函數是線程不安全的.可是,當iPod EQ unit還沒有主動參與audio processing graph時,必須在序列時執行它,由於此時沒有調用AUGraphUpdate函數。AUGraphSetNodeInputCallback
將「beats sound」回調函數添加到iPod EQ input端。上面1,2,4步使用AUGraph*
開頭的函數,都會被添加到graph的任務執行列表中.經過調用AUGraphUpdate
執行這些未開始任務.若是成功返回,則graph已經被動態從新配置而且iPod EQ也已經就位正在處理音頻數據.
在audio processing graph可使用相似生產者消費者模式,消費者在須要更多音頻數據時通知生產者。請求音頻數據流的方向與音頻流提供的方向正好相反.
對一組音頻數據的每一個請求稱爲渲染調用(render call),也稱爲拉流(pull)。該圖表示拉流爲灰色「控制流」箭頭。拉流請求的數據更恰當地稱爲一組音頻樣本幀(audio sample frames)。反過來,響應拉流而提供的一組音頻樣本幀被稱爲slice.提供slice的代碼稱爲渲染回調函數( render callback function).
AUGraphStart
函數.虛擬輸出設備調用Remote I/O unit output element的回調函數.該調用請求一片處理過的音頻數據幀。爲了從本地文件或內存中將音頻傳給audio unit的input bus.使用符合AURenderCallback
回調函數完成.audio unit input須要一些音頻數據幀將調用回調函數.
回調函數是惟一能夠對音頻幀作處理的地方,同時,回調函數必須遵照嚴格的性能要求.以錄製爲例,回調函數是按照固定時間間隔進行喚醒調用,若是咱們在間隔時間內尚未處理完上一幀數據,那麼下一幀數據到達時將產生一個間隙的效果.所以回調函數內應儘可能避免加鎖,分配內存,訪問文件系統或網絡鏈接,或以其餘方式在回調函數的主體中執行耗時的任務。
static OSStatus MyAURenderCallback (
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData
) { /* callback body *
複製代碼
*ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
當您但願產生靜默時,還必須顯式地將ioData參數指向的緩衝區設置爲0。inRefCon
爲每一個bus.ioData
參數中.struct AudioStreamBasicDescription {
Float64 mSampleRate;
UInt32 mFormatID;
UInt32 mFormatFlags;
UInt32 mBytesPerPacket;
UInt32 mFramesPerPacket;
UInt32 mBytesPerFrame;
UInt32 mChannelsPerFrame;
UInt32 mBitsPerChannel;
UInt32 mReserved;
};
typedef struct AudioStreamBasicDescription AudioStreamBasicDescription;
size_t bytesPerSample = sizeof (AudioUnitSampleType);
AudioStreamBasicDescription stereoStreamFormat = {0};
stereoStreamFormat.mFormatID = kAudioFormatLinearPCM;
stereoStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
stereoStreamFormat.mBytesPerPacket = bytesPerSample;
stereoStreamFormat.mBytesPerFrame = bytesPerSample;
stereoStreamFormat.mFramesPerPacket = 1;
stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample;
stereoStreamFormat.mChannelsPerFrame = 2; // 2 indicates stereo
stereoStreamFormat.mSampleRate = graphSampleRate;
複製代碼
首先,應該肯定採樣值的數據類型,上面使用的是AudioUnitSampleType
,這是大部分audio units推薦的類型,在iOS平臺上,被定義爲8.24位固定的整型數據.接下來定義ASBD類型變量,初始化爲0表明不包含任何數據.(注意,不能跳過該步,不然可能產生一些想不到的問題.). 而後就是對ASBD賦值,設備PCM類型表示未壓縮的音頻數據,
mFormatFlags(metaflag): 某些audio unit使用不規則的音頻數據格式即不一樣的音頻數據類型,則mFormatFlags字段須要不一樣的標誌集。 例如:3D Mixer unit須要UInt16
類型數據做爲採樣值且mFormatFlags
須要設置爲kAudioFormatFlagsCanonical
.
mBytesPerPacket: 每一個音頻包中有多少字節數
mBytesPerFrame: 每一幀中有多少字節
mFramesPerPacket: 每一個包中有多少幀
mBitsPerChannel: 每一個聲道有多少位
在audio processing graph中你必須在關鍵點設置音頻數據格式.其餘點,系統將會設置這個格式.IOS 設備上的音頻輸入和輸出硬件具備系統肯定的音頻流格式,而且格式始終是未壓縮的, 採用交錯的線性 PCM 格式.
如上圖, 麥克風表示輸入的音頻硬件。系統肯定輸入硬件的音頻流格式, 並將其施加到 Remote I/O unit’s 的input element的output scope內。一樣,揚聲器表示輸出音頻硬件。系統肯定輸出硬件的流格式,並將其施加到Remote I/O unit’s output element的output scope。
開發者則負責在兩個Remote I/O unit’s elements之間創建音頻流格式.I/O unit則自動在硬件與自身鏈接的一端作一個必要的格式轉換.
audio unit鏈接的一個關鍵功能 (如圖1-8 所示) 是, 該鏈接將音頻數據流格式從其源音頻單元的輸出傳播到目標音頻單元的輸入。這是一個關鍵點, 所以值得強調的是: 流格式傳播是經過音頻單元鏈接的方式進行的, 僅在一個方向上進行--從源音頻單元的輸出到目標音頻單元的輸入。
雖然咱們經過ASBD靈活的設置音頻數據流的屬性(如採樣率),可是建議仍是使用當前設備硬件默認使用值.由於若是保持一致,系統不須要作採樣率轉換,這能夠下降能耗同時提升音頻質量.
正確的設置流格式在創建音頻流中顯得相當重要.這些模式大多依賴於音頻流格式從源到目的地的自動傳播,它們之間經過audio unit鏈接.合理利用傳播的特性能夠減小代碼書寫量,同時,你必須保證清楚瞭解每種模式須要如何進行設置.能夠在不使用audio processing graph的狀況下實現任一一種模式,可是使用它能夠減小代碼書寫量並支持動態從新配置.
I/O Pass Through傳遞模式在不處理音頻的狀況下將傳入的音頻直接發送到輸出硬件.
如上圖所示,輸入端硬件將它的格式告訴Remote I/O unit的input element.開發者則在I/O unit的輸出端指定了流格式,audio unit內部將根據需求自動進行轉換,爲了不採樣率轉換,咱們在定義ASBD時最好使用硬件使用的採樣率.在上圖,咱們沒必要指定I/O unit的輸出element,由於數據格式會從輸入的element傳給輸出.同理,傳給硬件的流將會根據硬件須要完成一次自動轉換.
app能夠添加一個或多個audio unit在Remote I/O unit’s elements之間.例如使用多通道Mixer unit將傳入的麥克風音頻定位到立體聲域中,或提供輸出音量控制,在這中模式下,仍然沒有用到回調函數.它簡化了模式,但限制了其實用性。若是沒有呈現回調函數,就沒法直接操做音頻。
在這種模式下,和Pass Through模式相同,你能夠配置這兩個Remote I/O unit.爲了設置多通道Mixer unit,你必須把你的音頻流採樣率設置給mixer output.mixer的輸入端音頻流格式會自動設置經過接收從I/O unit輸出端傳遞來的音頻流.同理,Output element輸入端的格式也將自動設置經過流傳遞.
使用此模式必須設置
kAudioUnitProperty_MaximumFramesPerSlice
屬性.
經過註冊回調函數在Remote I/O unit的input,output elements之間,開發者能夠在音頻數據送到輸出硬件以前操控它.好比,經過回調函數調節輸出音頻的音量,還能夠添加顫音、環調製、回波或其餘效果(Accelerate framework中有相關API).
如圖所示,這個模式使用兩個Remote I/O unit, 回調函數被附加在output element的input scope.當output element須要音頻數據時,系統會觸發回調,緊接着,回調完成後系統將數據傳給output element的input scope.
必須顯式啓動input在Remote I/O unit.由於它默認是禁止的.
該模式一般用於遊戲,專業音頻app使用.簡單的說,該模式在直接鏈接在Remote I/O unit的output element的input scope.能夠利用此模式完成複雜的音頻結構,如將幾種不一樣的聲音混合在一塊兒,而後經過輸出硬件播放他們,以下圖.
如上圖所示,注意iPod EQ須要開發者設置Input,output二者的流格式.而 Multichannel Mixer僅僅只須要設置它輸出的採樣率便可.正如前面說到過,完整的音頻流格式信息會在傳遞的過程當中自動賦值.
audio unit還有兩種主要的設計模式.
audio session是app與硬件交互的中介。設置採樣率,
NSError *audioSessionError = nil;
AVAudioSession *mySession = [AVAudioSession sharedInstance]; // 1
[mySession setPreferredHardwareSampleRate: graphSampleRate // 2
error: &audioSessionError];
[mySession setCategory: AVAudioSessionCategoryPlayAndRecord // 3
error: &audioSessionError];
[mySession setActive: YES // 4
error: &audioSessionError];
self.graphSampleRate = [mySession currentHardwareSampleRate]; // 5
複製代碼
AVAudioSessionCategoryPlayAndRecord
指的是支持音頻輸入與輸出。你還能夠配置一些其餘功能,如採樣率爲44.1 kHz默認的duration是大概23ms,至關於每次採集1024個採樣點。若是你的app要求延遲很低,你能夠最低設置0.005ms(至關於256個採樣點)
self.ioBufferDuration = 0.005;
[mySession setPreferredIOBufferDuration: ioBufferDuration
error: &audioSessionError];
複製代碼
配置完audio session後還沒法直接得到audio unit,經過AudioComponentDescription
賦值能夠獲得一個指定的audio unit. (1.3中講到如何賦值)
AUGraph
對象(表明 audio processing graph)。AUNode
對象(每個表明一個 audio unit in the graph.)。AUGraph processingGraph;
NewAUGraph (&processingGraph);
AUNode ioNode;
AUNode mixerNode;
AUGraphAddNode (processingGraph, &ioUnitDesc, &ioNode);
AUGraphAddNode (processingGraph, &mixerDesc, &mixerNode);
複製代碼
調用AUGraphAddNode
函數後,graph被實例化而且擁有nodes.爲了打開graph而且實例化audio unit須要調用AUGraphOpen
AUGraphOpen (processingGraph);
經過AUGraphNodeInfo
函數獲取對audio unit實例的引用
AudioUnit ioUnit;
AudioUnit mixerUnit;
AUGraphNodeInfo (processingGraph, ioNode, NULL, &ioUnit);
AUGraphNodeInfo (processingGraph, mixerNode, NULL, &mixerUnit);
複製代碼
iOS中每種audio unit都有其配置的方法,咱們應該熟悉一些經常使用的audio unit配置.
Remote I/O unit, 默認輸入禁用,輸出可用.若是僅僅使用輸入,你必須相應地從新配置 I/O unit.除了Remote I/O與Voice-Processing I/O unit以外全部的audio unit都必須配置kAudioUnitProperty_MaximumFramesPerSlice
屬性.該屬性確保audio unit 準備好響應於回調函數產生足夠數量的音頻數據幀。
對於須要使用回調函數的設計模式,咱們必須註冊並實現相應的回調函數.此外,還能夠經過回調函數拉取音頻數據流.
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = &renderCallback;
callbackStruct.inputProcRefCon = soundStructArray;
AudioUnitSetProperty (
myIOUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0, // output element
&callbackStruct,
sizeof (callbackStruct)
);
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = &renderCallback;
callbackStruct.inputProcRefCon = soundStructArray;
AUGraphSetNodeInputCallback (
processingGraph,
myIONode,
0, // output element
&callbackStruct
);
// ... some time later
Boolean graphUpdated;
AUGraphUpdate (processingGraph, &graphUpdated);
複製代碼
使用AUGraphConnectNodeInput
與AUGraphDisconnectNodeInput
函數能夠創建,斷開Node.它們是線程安全的而且下降代碼的開銷,由於若是不適用graph咱們將必須手動實現.
AudioUnitElement mixerUnitOutputBus = 0;
AudioUnitElement ioUnitOutputElement = 0;
AUGraphConnectNodeInput (
processingGraph,
mixerNode, // source node
mixerUnitOutputBus, // source node bus
iONode, // destination node
ioUnitOutputElement // desinatation node element
);
複製代碼
固然,咱們也能夠直接使用audio unit的屬性創建鏈接,以下.
AudioUnitElement mixerUnitOutputBus = 0;
AudioUnitElement ioUnitOutputElement = 0;
AudioUnitConnection mixerOutToIoUnitIn;
mixerOutToIoUnitIn.sourceAudioUnit = mixerUnitInstance;
mixerOutToIoUnitIn.sourceOutputNumber = mixerUnitOutputBus;
mixerOutToIoUnitIn.destInputNumber = ioUnitOutputElement;
AudioUnitSetProperty (
ioUnitInstance, // connection destination
kAudioUnitProperty_MakeConnection, // property key
kAudioUnitScope_Input, // destination scope
ioUnitOutputElement, // destination element
&mixerOutToIoUnitIn, // connection definition
sizeof (mixerOutToIoUnitIn)
);
複製代碼
通常而言,咱們須要提供一個用戶界面,讓用戶微調音頻行爲。能夠定製用戶界面以容許用戶調整特定的音頻單元參數,並在某些特殊狀況下調整音頻單元屬性。
調用AUGraphInitialize
初始化audio processing graph.
OSStatus result = AUGraphInitialize (processingGraph);
// Check for error. On successful initialization, start the graph...
AUGraphStart (processingGraph);
// Some time later
AUGraphStop (processingGraph);
複製代碼
經過函數返回值能夠檢查調用是否成功.
請留意函數調用之間的依賴,例如,僅僅只能在audio processing graph初始化成功後再開啓它.其次,利用CAShow
函數能夠打印當前graph的狀態.
確保ASBD初始化賦值爲0. AudioStreamBasicDescription stereoStreamFormat = {0};
.將ASBD的字段初始化爲0可確保沒有字段包含垃圾數據。(注意:做爲類聲明中的實例變量 - 其字段會自動初始化爲0,無需本身初始化它們)
- (void) printASBD: (AudioStreamBasicDescription) asbd {
char formatIDString[5];
UInt32 formatID = CFSwapInt32HostToBig (asbd.mFormatID);
bcopy (&formatID, formatIDString, 4);
formatIDString[4] = '\0';
NSLog (@" Sample Rate: %10.0f", asbd.mSampleRate);
NSLog (@" Format ID: %10s", formatIDString);
NSLog (@" Format Flags: %10X", asbd.mFormatFlags);
NSLog (@" Bytes per Packet: %10d", asbd.mBytesPerPacket);
NSLog (@" Frames per Packet: %10d", asbd.mFramesPerPacket);
NSLog (@" Bytes per Frame: %10d", asbd.mBytesPerFrame);
NSLog (@" Channels per Frame: %10d", asbd.mChannelsPerFrame);
NSLog (@" Bits per Channel: %10d", asbd.mBitsPerChannel);
}
複製代碼
iOS提供了三種I/O unit.大部分應用使用Remote I/O unit,它鏈接到輸入和輸出音頻硬件,並提供對各個傳入和傳出音頻樣本值的低延遲訪問.對於VoIP應用,Voice-Processing I/O unit經過添加聲學回聲消除和其餘功能來擴展遠程I / O單元。要將音頻發送迴應用程序而不是輸出音頻硬件,請使用通用輸出單元。
Remote I/O unit(子類型kAudioUnitSubType_RemoteIO)鏈接到設備硬件,用於輸入,輸出或同時輸入和輸出。用於播放,錄製或低延遲同時輸入和輸出,不須要回聲消除。
設備的音頻硬件將其音頻流格式強制放置在 Remote I/O unit的外側。audio unit提供硬件音頻格式和應用音頻格式之間的格式轉換,經過附帶的格式轉換器audio unit進行格式轉換.
input element input scope 從輸入硬件獲取音頻格式, output element output scope從輸出硬件獲取音頻格式,
在input元素的輸出範圍上設置應用程序格式。 input元素根據須要在其輸入和輸出範圍之間執行格式轉換。使用應用程序流格式的硬件採樣率。若是輸出元素的輸入範圍由音頻單元鏈接提供,則它從該鏈接獲取其流格式。可是,若是它由渲染回調函數提供,請在其上設置應用程序格式。
Audio unit feature | Details |
---|---|
Elements | 一個input element,一個output element |
建議使用屬性 | kAudioFormatLinearPCM,kAudioFormatFlags,AudioUnitSampleType,AudioUnitCanonical |
注意點 | Remote I/O unit朝外側從音頻硬件獲取其格式,input element從輸入端硬件獲取,output element 從輸出端硬件獲取. |
屬性注意 | 不須要設置kAudioUnitProperty_MaximumFramesPerSlice |
Voice-Processing I/O unit(子類型kAudioUnitSubType_VoiceProcessingIO)具備 Remote I/O unit 的特性,而且添加了回聲抑制。它還增長了自動增益校訂,語音處理質量調整和靜音功能。這是用於VoIP(互聯網協議語音)應用程序的正確I/O unit。
在將audio processing graph的輸出發送到應用程序而不是輸出音頻硬件時,請使用此類型爲kAudioUnitSubType_GenericOutput的音頻單元。一般使用Generic Output Unit進行離線音頻處理。與其餘I / O units同樣,Generic Output unit包含格式轉換器。所以能夠在audio processing graph中使用的流格式與所需格式之間執行格式轉換。
iOS提供兩種mixer units。在大多數狀況下,您應該使用Multichannel Mixer unit,它能夠爲任意數量的單聲道或立體聲流提供混音。若是您須要3D Mixer unit的功能,請使用OpenAL。 OpenAL創建在3D混音器單元之上,提供與簡單API相同的性能,很是適合遊戲應用程序開發。
默認狀況下,kAudioUnitProperty_MaximumFramesPerSlice屬性設置爲1024,當屏幕鎖定而且顯示器休眠時,這是不夠的。若是您的應用在屏幕鎖定時播放音頻,則必須增長此屬性的值,除非音頻輸入處於活動狀態。作以下:
Multichannel Mixer unit(子類型kAudioUnitSubType_MultiChannelMixer)可接收任意數量的單聲道或立體聲流,並將它們組合成單個立體聲輸出。它控制每一個輸入和輸出的音頻增益,並容許您分別打開或關閉每一個輸入。從iOS 4.0開始,多聲道混音器支持每一個輸入的立體聲聲像。
Audio unit feature | Details |
---|---|
Elements | 一個或多個(單聲道或多聲道)input element,一個多聲道output element |
建議使用屬性 | kAudioFormatLinearPCM,kAudioFormatFlags,AudioUnitSampleType,AudioUnitCanonical |
注意點 | 若是輸入由audio unit鏈接則從該鏈接獲取其流格式。若是輸入由回調函數提供在bus上設置完整的流格式,使用與回調提供的數據相同的流格式。在output scope,僅須要設置採樣率。 |
屬性 | kAudioUnitProperty_MeteringMode |
注意點: iPod EQ單元提供一組預約義的色調均衡曲線做爲出廠預設。經過訪問音頻單元的kAudioUnitProperty_FactoryPresets屬性獲取可用EQ設置數組。使用它做爲kAudioUnitProperty_PresentPreset屬性的值來應用設置。
3D Mixer unit: 控制每一個輸入的立體聲聲像,播放速度和增益,並控制其餘特徵,例如與收聽者的視距,輸出具備音頻增益控制。一般,若是須要3D Mixer unit的功能,最佳選擇是使用OpenAL.
Audio unit feature | Details |
---|---|
Elements | 一個或多個單聲道input element,一個多聲道output element |
建議使用屬性 | UInt16,kAudioFormatFlagsAudioUnitCanonical |
注意點 | 若是輸入由audio unit鏈接則從該鏈接獲取其流格式。若是輸入由回調函數提供在bus上設置完整的流格式,使用與回調提供的數據相同的流格式。在output scope,僅須要設置採樣率。 |
注意點: iPod EQ單元提供一組預約義的色調均衡曲線做爲出廠預設。經過訪問音頻單元的kAudioUnitProperty_FactoryPresets屬性獲取可用EQ設置數組。使用它做爲kAudioUnitProperty_PresentPreset屬性的值來應用設置。
iPod EQ unit (子類型kAudioUnitSubType_AUiPodEQ)是iOS 4中提供的惟一效果單元。這與內置iPod應用程序使用的均衡器相同。要查看該音頻設備的iPod應用程序用戶界面,請轉至設置> iPod> EQ。該音頻單元提供一組預設均衡曲線,如低音加強器,流行音樂和口語。
Audio unit feature | Details |
---|---|
Elements | 一個input element,一個output element (該element能夠是單聲道或雙聲道) |
建議使用屬性 | kAudioFormatLinearPCM,AudioUnitSampleType,kAudioFormatFlagsAudioUnitCanonical |
注意點 | 若是輸入由audio unit鏈接則從該鏈接獲取其流格式。若是輸入由回調函數提供在bus上設置完整的流格式,使用與回調提供的數據相同的流格式。在output scope,設置用於輸入的相同完整流格式。 |
Properties | kAudioUnitProperty_FactoryPresets,kAudioUnitProperty_PresentPreset |
注意點: iPod EQ單元提供一組預約義的色調均衡曲線做爲出廠預設。經過訪問音頻單元的kAudioUnitProperty_FactoryPresets屬性獲取可用EQ設置數組。使用它做爲kAudioUnitProperty_PresentPreset屬性的值來應用設置。
默認狀況下,kAudioUnitProperty_MaximumFramesPerSlice屬性設置爲1024,當屏幕鎖定而且顯示器休眠時,這是不夠的。若是您的應用在屏幕鎖定時播放音頻,則必須增長此屬性的值,除非音頻輸入處於活動狀態。作以下:
此表提供了訪問每一個iOS audio unit的動態連接庫所需的標識符鍵以及其簡要說明。
名稱與描述 | 鍵名稱 | 相應編解碼器 |
---|---|---|
Converter unit (提供音頻格式轉換在線性PCM與其餘壓縮格式) | kAudioUnitType_FormatConverter,kAudioUnitSubType_AUConverter,kAudioUnitManufacturer_Apple | aufc,conv,appl |
iPod Equalizer unit(提供iPod均衡器的功能) | kAudioUnitType_Effect | kAudioUnitSubType_AUiPodEQ |
3D Mixer unit (支持混合多個音頻流,輸出平移,採樣率轉換等) | kAudioUnitType_Mixer,kAudioUnitSubType_AU3DMixerEmbedded,kAudioUnitManufacturer_Apple | aumx,3dem,appl |
Multichannel Mixer unit (支持將多個音頻流混合到單個流中) | kAudioUnitType_Mixer,kAudioUnitSubType_MultiChannelMixer,kAudioUnitManufacturer_Apple | aumx,mcmx,appl |
Generic Output unit (支持轉換爲線性PCM格式和從線性PCM格式轉換;可用於啓動和中止graph) | kAudioUnitType_Output,kAudioUnitSubType_GenericOutput,kAudioUnitManufacturer_Apple | auou,genr,appl |
Remote I/O unit(鏈接到設備硬件以進行輸入,輸出或同時輸入和輸出) | kAudioUnitType_Output,kAudioUnitSubType_RemoteIO,kAudioUnitManufacturer_Apple | auou,rioc,appl |
Voice Processing I/O unit(具備I / O單元的特性,併爲雙向通訊增長了回聲抑制功能) | kAudioUnitType_Output,kAudioUnitSubType_VoiceProcessingIO,kAudioUnitManufacturer_Apple | auou,vpio,appl |