版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.07.05 |
前言
AudioUnit框架作為您的應(yīng)用程序添加復(fù)雜的音頻操作和處理功能。 創(chuàng)建在主機應(yīng)用程序中生成或修改音頻的音頻單元擴展花竞。接下來幾篇我們就一起看一下這個框架劲件,感興趣的看上面幾篇文章。
1. AudioUnit框架詳細解析(一) —— 基本概覽
2. AudioUnit框架詳細解析(二) —— 關(guān)于Audio Unit Hosting之概覽(一)
3. AudioUnit框架詳細解析(三) —— 關(guān)于Audio Unit Hosting之如何使用本文檔和參考資料(二)
4. AudioUnit框架詳細解析(四) —— 音頻單元提供快速的模塊化音頻處理之iOS中的Audio Units(一)
5. AudioUnit框架詳細解析(五) —— 音頻單元提供快速的模塊化音頻處理之在Concert中使用兩個音頻單元API(二)
6. AudioUnit框架詳細解析(六) —— 音頻單元提供快速的模塊化音頻處理之使用標識符來指定和獲取音頻單元(三)
7. AudioUnit框架詳細解析(七) —— 音頻單元提供快速的模塊化音頻處理之使用范圍和元素來指定音頻單元的部分(四)
8. AudioUnit框架詳細解析(八) —— 音頻單元提供快速的模塊化音頻處理之使用屬性來配置音頻單元(五)
9. AudioUnit框架詳細解析(九) —— 音頻單元提供快速的模塊化音頻處理之使用參數(shù)和UIKit為用戶提供控制(六)
10. AudioUnit框架詳細解析(十) —— 音頻單元提供快速的模塊化音頻處理之I / O單元的基本特性(七)
11. AudioUnit框架詳細解析(十一) —— 音頻處理圖管理音頻單元之音頻處理圖具有一個I / O單元(一)
12. AudioUnit框架詳細解析(十二) —— 音頻處理圖管理音頻單元之音頻處理圖提供線程安全性(二)
13. AudioUnit框架詳細解析(十三) —— 音頻處理圖管理音頻單元之音頻使用Pull通過圖表(三)
14. AudioUnit框架詳細解析(十四) —— 呈現(xiàn)回調(diào)函數(shù)將音頻饋送到音頻單元之了解音頻單元呈現(xiàn)回調(diào)函數(shù)(一)
15. AudioUnit框架詳細解析(十五) —— 音頻流格式啟用數(shù)據(jù)流之使用AudioStreamBasicDescription結(jié)構(gòu)(一)
16. AudioUnit框架詳細解析(十六) —— 音頻流格式啟用數(shù)據(jù)流之了解何處以及如何設(shè)置流格式(二)
17. AudioUnit框架詳細解析(十七) —— 從選擇設(shè)計模式開始之I / O傳遞(一)
18. AudioUnit框架詳細解析(十八) —— 從選擇設(shè)計模式開始之沒有渲染回調(diào)函數(shù)的I / O(二)
19. AudioUnit框架詳細解析(十九) —— 從選擇設(shè)計模式開始之具有渲染回調(diào)函數(shù)的I / O(三)
20. AudioUnit框架詳細解析(二十) —— 從選擇設(shè)計模式開始之僅具有渲染回調(diào)函數(shù)的輸出(四)
21. AudioUnit框架詳細解析(二十一) —— 從選擇設(shè)計模式開始之其他音頻單元Hosting設(shè)計模式(五)
Constructing Your App - 構(gòu)建您的應(yīng)用程序
無論您選擇哪種設(shè)計模式约急,構(gòu)建音頻單元hosting應(yīng)用程序的步驟基本相同:
- 配置音頻會話零远。
- 指定音頻單元。
- 創(chuàng)建音頻處理圖厌蔽,然后獲取音頻單元牵辣。
- 配置音頻單元。
- 連接音頻單元節(jié)點奴饮。
- 提供用戶界面纬向。
- 初始化然后啟動音頻處理圖。
Configure Your Audio Session - 配置音頻會話
接下來拐云,使用音頻會話對象請求系統(tǒng)使用您的首選采樣率作為設(shè)備硬件采樣率罢猪,如Listing 2-1
所示。 這里的目的是避免硬件和您的應(yīng)用程序之間的采樣率轉(zhuǎn)換叉瘩。 這可以最大限度地提高CPU性能和音質(zhì)膳帕,并最大限度地減少電池消耗。
Listing 2-1 Configuring an audio session
self.graphSampleRate = 44100.0; // Hertz
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
前面的行執(zhí)行以下操作:
- 獲取應(yīng)用程序的單例音頻會話對象的引用薇缅。
- 請求硬件采樣率危彩。 系統(tǒng)可能會或可能不會授予請求,具體取決于設(shè)備上的其他音頻活動泳桦。
- 請求所需的音頻會話類別汤徽。 此處指定的
play and record
類別支持音頻輸入和輸出。
- 請求所需的音頻會話類別汤徽。 此處指定的
- 請求激活您的音頻會話灸撰。
- 激活音頻會話后谒府,根據(jù)系統(tǒng)提供的實際采樣率更新您自己的采樣率變量拼坎。
您可能需要配置另一個硬件特性:音頻硬件I / O緩沖區(qū)持續(xù)時間。 在44.1 kHz采樣率下完疫,默認持續(xù)時間約為23 ms泰鸡,相當(dāng)于1,024個樣本的切片大小。 如果您的應(yīng)用中的I / O延遲至關(guān)重要壳鹤,您可以請求較小的持續(xù)時間盛龄,最低約0.005毫秒(相當(dāng)于256個樣本),如下所示:
self.ioBufferDuration = 0.005;
[mySession setPreferredIOBufferDuration: ioBufferDuration
error: &audioSessionError];
有關(guān)如何配置和使用音頻會話對象的完整說明芳誓,請參閱Audio Session Programming Guide
余舶。
Specify the Audio Units You Want - 指定您想要的音頻單元
在運行時,運行音頻會話配置代碼后锹淌,您的應(yīng)用尚未獲取音頻單元匿值。 您可以使用AudioComponentDescription
結(jié)構(gòu)指定所需的每個。 有關(guān)如何執(zhí)行此操作赂摆,請參閱Use Identifiers to Specify and Obtain Audio Units
千扔。 每個iOS音頻單元的標識符鍵列在Identifier Keys for Audio Units
中。
獲取指定的音頻單元說明符库正,然后根據(jù)您選擇的模式構(gòu)建音頻處理圖。
Build an Audio Processing Graph - 構(gòu)建音頻處理圖
在此步驟中厘唾,您將創(chuàng)建本章第一部分中介紹的其中一種設(shè)計模式的框架褥符。 具體來說,你:
- 實例化
AUGraph opaque
類型抚垃。 該實例表示音頻處理圖喷楣。
- 實例化
- 實例化一個或多個
AUNode
不透明類型,每個類型代表圖中的一個音頻單元鹤树。
- 實例化一個或多個
- 將節(jié)點添加到圖表中铣焊。
- 打開圖形并實例化音頻單元。
- 獲取音頻單元的引用罕伯。
Listing 2-2
顯示了如何為包含遠程I / O單元和多通道混合器單元的圖形執(zhí)行這些步驟曲伊。 它假設(shè)您已經(jīng)為每個音頻單元定義了AudioComponentDescription
結(jié)構(gòu)。
Listing 2-2 Building an audio processing graph
AUGraph processingGraph;
NewAUGraph (&processingGraph);
AUNode ioNode;
AUNode mixerNode;
AUGraphAddNode (processingGraph, &ioUnitDesc, &ioNode);
AUGraphAddNode (processingGraph, &mixerDesc, &mixerNode);
AUGraphAddNode
函數(shù)調(diào)用使用音頻單元說明符ioUnitDesc
和mixerDesc
追他。 此時坟募,圖形將被實例化,并擁有您將在應(yīng)用程序中使用的節(jié)點邑狸。 要打開圖形并實例化音頻單元懈糯,請調(diào)用AUGraphOpen:
AUGraphOpen (processingGraph);
然后,通過AUGraphNodeInfo
函數(shù)獲取對音頻單元實例的引用单雾,如下所示:
AudioUnit ioUnit;
AudioUnit mixerUnit;
AUGraphNodeInfo (processingGraph, ioNode, NULL, &ioUnit);
AUGraphNodeInfo (processingGraph, mixerNode, NULL, &mixerUnit);
ioUnit
和mixerUnit
變量現(xiàn)在包含對圖形中音頻單元實例的引用赚哗,允許您配置并互連音頻單元她紫。
Configure the Audio Units - 配置音頻單元
每個iOS音頻設(shè)備都需要自己的配置,如Using Specific Audio Units
中所述屿储。 但是贿讹,有些配置很常見,所有iOS音頻開發(fā)人員都應(yīng)該熟悉它們扩所。
默認情況下围详,遠程I / O單元已啟用輸出并禁用輸入。 如果您的應(yīng)用程序同時執(zhí)行I / O或僅使用輸入祖屏,則必須相應(yīng)地重新配置I / O單元助赞。 有關(guān)詳細信息,請參閱Audio Unit Properties Reference
中的kAudioOutputUnitProperty_EnableIO
屬性袁勺。
除了遠程I/O和語音處理I/O單元之外雹食,所有iOS音頻單元都需要配置它們的kAudioUnitProperty_MaximumFramesPerSlice
屬性。此屬性確保音頻單元準備生成足夠數(shù)量的音頻數(shù)據(jù)幀以響應(yīng)呈現(xiàn)調(diào)用期丰。有關(guān)詳細信息群叶,請參見Audio Unit Properties Reference
中的kAudioUnitProperty_MaximumFramesPerSlice
。
所有音頻單元都需要在輸入钝荡、輸出或兩者上定義它們的音頻流格式街立。有關(guān)音頻流格式的解釋,請參閱Audio Stream Formats Enable Data Flow
埠通。對于各種iOS音頻單元的特定流格式要求赎离,請參見Using Specific Audio Units
。
Write and Attach Render Callback Functions - 編寫并附加呈現(xiàn)回調(diào)函數(shù)
對于采用渲染回調(diào)函數(shù)的設(shè)計模式端辱,您必須編寫這些函數(shù)梁剔,然后將它們附加到正確的點。Render Callback Functions Feed Audio to Audio Units
介紹了這些回調(diào)的作用并說明了它們的工作原理舞蔽。 有關(guān)工作回調(diào)的示例荣病,請查看iOS參考庫中的各種音頻單元示例代碼項目,包括音頻混合器(MixerHost)
和aurioTouch
以及SynthHost
渗柿。
當(dāng)音頻不流動時个盆,您可以使用音頻單元API立即附加渲染回調(diào),如Listing 2-3
所示做祝。
Listing 2-3 Attaching a render callback immediately
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = &renderCallback;
callbackStruct.inputProcRefCon = soundStructArray;
AudioUnitSetProperty (
myIOUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0, // output element
&callbackStruct,
sizeof (callbackStruct)
);
通過使用音頻處理圖API砾省,您可以以線程安全的方式附加渲染回調(diào),即使在音頻流動時也是如此混槐。 Listing 2-4
顯示了如何做编兄。
Listing 2-4 Attaching a render callback in a thread-safe manner
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = &renderCallback;
callbackStruct.inputProcRefCon = soundStructArray;
AUGraphSetNodeInputCallback (
processingGraph,
myIONode,
0, // output element
&callbackStruct
);
// ... some time later
Boolean graphUpdated;
AUGraphUpdate (processingGraph, &graphUpdated);
Connect the Audio Unit Nodes - 連接音頻單元節(jié)點
在大多數(shù)情況下,使用音頻處理圖API中的AUGraphConnectNodeInput
和AUGraphDisconnectNodeInput
函數(shù)建立或斷開音頻單元之間的連接是最好和最容易的声登。 這些函數(shù)是線程安全的狠鸳,可以避免顯式定義連接的編碼開銷揣苏,因為在不使用圖形時必須這樣做。
Listing 2-5
顯示了如何使用音頻處理圖API將混合器節(jié)點的輸出連接到I / O單元輸出element
的輸入件舵。
Listing 2-5 Connecting two audio unit nodes using the audio processing graph API
AudioUnitElement mixerUnitOutputBus = 0;
AudioUnitElement ioUnitOutputElement = 0;
AUGraphConnectNodeInput (
processingGraph,
mixerNode, // source node
mixerUnitOutputBus, // source node bus
iONode, // destination node
ioUnitOutputElement // desinatation node element
);
或者卸察,您可以使用音頻單元屬性機制直接建立和斷開音頻單元之間的連接。 為此铅祸,請使用AudioUnitSetProperty
函數(shù)以及kAudioUnitProperty_MakeConnection
屬性坑质,如Listing 2-6
所示。 此方法要求您為每個連接定義AudioUnitConnection
結(jié)構(gòu)以用作其屬性值临梗。
Listing 2-6 Connecting two audio units directly
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,
ioUnitOutputElement,
&mixerOutToIoUnitIn,
sizeof (mixerOutToIoUnitIn)
);
// destination scope
// destination element
// connection definition
Provide a User Interface - 提供一個用戶界面
此時涡扼,在構(gòu)建應(yīng)用程序時,音頻單元(通常是音頻處理圖形)已完全構(gòu)建和配置盟庞。在許多情況下吃沪,您需要提供一個用戶界面,讓您的用戶微調(diào)音頻行為什猖。您可以定制用戶界面以允許用戶調(diào)整特定的音頻單元參數(shù)票彪,并在某些特殊情況下調(diào)整音頻單元屬性。在任何一種情況下不狮,用戶界面還應(yīng)提供有關(guān)當(dāng)前設(shè)置的視覺反饋降铸。
Use Parameters and UIKit to Give Users Control
介紹了構(gòu)建用戶界面以讓用戶控制參數(shù)值的基礎(chǔ)知識。有關(guān)工作示例摇零,請查看示例代碼項目Audio Mixer(MixerHost)
垮耳。
iPod EQ
單元是一種不尋常的情況,為了更改其活動均衡曲線遂黍,您可以更改kAudioUnitProperty_PresentPreset
屬性的值。無論音頻是否正在運行俊嗽,您都可以執(zhí)行此操作雾家。有關(guān)工作示例,請查看示例代碼項目iPhoneMixerEQGraphTest
绍豁。
Initialize and Start the Audio Processing Graph - 初始化并啟動音頻處理圖
在開始音頻流之前芯咧,必須通過調(diào)用AUGraphInitialize
函數(shù)來初始化音頻處理圖。 這個關(guān)鍵步驟:
- 通過為每個音頻單獨自動調(diào)用
AudioUnitInitialize
函數(shù)來初始化圖形所擁有的音頻單元竹揍。 (如果要在不使用圖形的情況下構(gòu)建處理鏈敬飒,則必須依次顯式初始化每個音頻單元。) - 驗證圖形的連接和音頻數(shù)據(jù)流格式芬位。
- 在音頻單元連接上傳播流格式无拗。
Listing 2-7
顯示了如何使用AUGraphInitialize。
Listing 2-7 Initializing and starting an audio processing graph
OSStatus result = AUGraphInitialize (processingGraph);
// Check for error. On successful initialization, start the graph...
AUGraphStart (processingGraph);
// Some time later
AUGraphStop (processingGraph);
后記
本篇主要講述了構(gòu)建您的應(yīng)用程序昧碉,感興趣的給個贊或者關(guān)注~~~~