Audio Unit详解

 

一、什么是Audio Unit

iOS提供了音频处理插件,支持混合、均衡、格式转换和实时输入/输出用于录制、播放、离线渲染和实时对话如VoIP(互联网协议语音)。你可以从iOS应用动态加载和使用它,这些强大和灵活的插件叫做Audio Unit。

Audio units通常工作在一个封闭对象的上下文中,该对象为audio processing graph,如下图。在此例中,你的app通过一个或多个callback functions发送audio到第一个audio unit,并对每个audio unit单独控制。I/O输出unit,直接连接输出硬件。

 

audio_unit.png

Audio units提供非常有用的个性化功能,如立体声像,混音,音量控制,音频电平测量。

二、Audio unit用在哪些方面

1、低延迟的同时音频I/O(输入和输出),例如VoIP应用
2、响应回放合成声音,例如用于音乐游戏或或合成乐器
3、使用特定的音频单元功能,例如回声消除,混音,或者音调均衡
4、一种处理链架构,让你灵活的将音频处理模块组装起来,这是iOS中唯一提供此功能的音频API

三、Audio Units in iOS

iOS根据功能提供了七种audio unit,分为四类,如下图:

 

 

category.png

 

3.1 Effect Unit
iOS4提供了一个effect unit,即iPod Equalizer,与内置iPod应用程序使用的均衡器相同。要查看该audio unit的iPod应用程序用户界面,请转至Setting> iPod> EQ。 使用此audio unit时,您必须提供自己的UI。 该audio unit提供一组预设均衡曲线,如低音增强器,流行音乐和口语

3.2 Mixer Units
iOS提供两个mixer units。3D Mixer unit是OpenAL构建的基础。在大多数情况下,如果需要3D Mixer unit的功能,最佳选择是使用OpenAL,它提供更适合游戏应用的更高级API。

Multichannel Mixer unit可以为任意数量的单声道或立体声流提供混音,并带有立体声输出。你可以打开或关闭每个输入,设置其输入增益,并设置其立体声平移位置。

3.3 I/O Units
iOS提供三个I/O unit。Remote I/O是最常用的。它连接输入和输出音频硬件,并为你提供对各个传入和传出音频样品值的低延迟访问。它提供硬件音频格式和应用程序音频格式之间的格式转换,通过Format Converter unit进行格式转换。

Voice-Processing I/O unit通过添加声学回声消除来扩展远程I/O单元,以用于VoIP或语音聊天应用程序。它还提供自动增益校正,语音处理质量和静音。

Generic Output unit不连接到音频硬件,而是提供将处理链的输出发送到应用程序。通常使用Generic Output unit 进行离线音频处理

3.4 Format Converter Unit
iOS4提供,通常通过I/O单元间接使用

五、使用两种方式来获取audio unit

要在运行时查找audio unit,需要为AudioComponentDescription数据结构指定type,subtype,manufacturer。无论是audio unit还是audio process graph API。

AudioComponentDescription audioDesc = {0};
audioDesc.componentType = kAudioUnitType_Output;
audioDesc.componentSubType = kAudioUnitSubType_RemoteIO;
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;

不同的audio unit的AudioComponentDescription设置如下图表:

 

 

component_description_setting.png

 

5.1 使用AudioComponentDescription初始化Audio Unit:

// find component
AudioComponent compoent = AudioComponentFindNext(NULL, &audioDesc);
// create new instance
AudioComponentInstanceNew(compoent, &audioUnit);

5.2 使用AUGraph来初始化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, &audioDesc, &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);

六、使用scope和elements来指定audio units的各个部分

Audio unit的各个部分组织成scopes and element,如下图所示。当调用函数去配置和控制audio unit时,你可以指定scope和element以标识函数的特点目标。

 

 

scope_elements.png

scope是audio unit内的编程上下文。虽然global scope可能暗示,但这些上下文从不嵌套。一般是使用一个常量值来自AudioUnitScope枚举。

element是嵌套在audio unit scope中的编程上下文。当element是输入或输出scope的一部分时,它类似于物理音频设备中的信号总线,因此有时成为总线。

global scope适用于整个audio unit,不与任何特定音频流相关联。它只有一个元素,即0。某些属性,如每个切片最大帧数(kAudioUnitProperty_MaximumFramesPerSlice),仅适用于global scope

输入和输出scopes直接参与通过audio unit移动一个或多个音频流。正如你所期待的那样,音频输入scope进入从输出scope离开。属性或参数可以作为整体应用于输入scope或输出scope,某些属性只能应用于scope特定的element

七、AudioUnitSetProperty配置audio unit

AudioUnitProperty是一个键值对。以下是audio unit开发中常用的一些属性:
kAudioOutputUnitProperty_EnableIO:用于在I/O unit上启用和禁用input or output。默认情况输出已启用,输入已禁用
kAudioUnitProperty_ElementCount:用于配置mixer unit上输入elements的数量
kAudioUnitProperty_MaximumFramesPerSlice:用于指定audio unit应准备响应于渲染调用而产生的音频数据最大帧数。不需要为I/O unit设置该值,因为它们已预先配置为处理系统请求的任何切片大小。对于其它audio unit,你必须将此属性设置为4096以处理屏幕睡眠,除非设备上正在运行音频输入。当音频输入运行时,系统保持切片大小为1024
kAudioUnitProperty_StreamFormat:用于指定特定音频单元输出或输出总线的音频流数据格式

发现属性的可用性,访问其值以及监听其值的更改使用以下函数

  • AudioUnitGetPropertyInfo:发现属性是否可用,则为你提供其值的数据大小以及是否可以更改该值
  • AudioUnitGetProperty,AudioUnitSetProperty:获取或设置属性的值
  • AudioUnitAddPropertyListener,AudioUnitRemovePropertyListenerWithUserData:安装或删除回调函数以监视属性值的更改

八、设置和获取parameter

audio unit parameter是用户可调节的设置,可在audio unit产生音频时改变。实际上,大多数parameters是在audio unit正在执行处理时,实时调整的。它也是键值对的形式。每个parameter的值是32位浮点类型。使用以下函数来设置或获取parameter的值:

  • AudioUnitGetParameter
  • AudioUnitSetParameter

九、I/O Unit的特征

 

I/O_unit.png

 

上图I/O Unit有两个element,但它们是独立的,例如,你可以根据应用程序的需要使用enable I/O属性(kAudioOutputUnitProperty_EnableIO)来独立启用或禁用某个element。每个element都有Input scope和Output scope。

I/O Unit的element 1连接音频的输入硬件,在上图中由麦克风表示。开发者只能访问控制Output scope
I/O Unit的element 0连接音频的输出硬件,在上图中由扬声器表示。开发者只能访问控制Input scope

input element is element 1(单词Input的字母“I”,类似1)
output element is element 0 (单词Output的字母“O”,类型0)

十、Auio Processing Graphs Manage Audio Units

使用数据类型AUGraph,用于构建和管理audio unit处理链。它可以利用多个音频单元和多个渲染回调函数的功能,允许你创建几乎任何你能想象的音频处理解决方案。

AUGraph是线程安全的,它能够动态地重新配置处理链。例如,你可以安全的插入均衡器,甚至可以在播放时交换混音器输入的不同渲染回调函数。事实上AUGraph是iOS唯一提供的API,用于在音频应用中执行此类动态重新配置。

AUNode来表示graph上下文中的单个audio unit。当使用graph是,你通常与node交互,而不是直接与audio unit交互

当你将graph放在一起时,你必须配置每个audio unit。为此你必须通过audio unit API直接与audio unit进行交互。audio unit node本身是不可配置的

你还可以将AUNode实例作为复杂graph中的元素,通过定义node来表示完整audio processing subgraph。在这种情况下,subgraph末尾必须是Generic Output unit(一种不连接到硬件设备的I/O unit)

总而言之,构建audio processing graph需要三个任务:
1、添加node到graph
2、直接配置nodes表示的audio units
3、互连nodes

AUGraph提供了以下函数来重新配置:
AUGraphAddNode,AUGraphRemoveNode:添加或移除audio unit node
AUGraphConnectNodeInput,AUGraphDisconnectNodeInput:添加或移除nodes之间的connections
AUGraphSetNodeInputCallback:connecting一个渲染回调给audio unit的input bus

十一、一些设计模式

I/O Pass Through

I/O pass-through模式将传入的音频直接发送到硬件输出,中间没有处理音频数据。

 

 

I/O.png

I/O Without a Render Callback Function

在Remote I/O unit的elements之间添加一个或多个其它audio unit,可以构建出更有用的应用,因为没有回调函数,则无法直接操作音频,限制了实用性。

 

 

I/O_No_Callback.png

I/O with a Render Callback Function

在Remote I/O unit之间添加一个回调函数,可以在传入音频到达输出硬件之前对其进行操作。比如使用渲染回调函数调整输出音量,添加颤音,铃声调制,回声或其他效果。通过使用Accelerate框架中提供的傅立叶和卷积函数,你的可能性是无穷尽的

 

 

render_callback.png

Output-Only with a Render Callback Function

适用于游戏和音乐合成app,将渲染回调函数直接连接到Remote I/O的Output element的input scope

 

 

only_output.png

complex pattern

 

complex.png

参考文章:
Audio Unit Hosting Guide for iOS

 

4人点赞

 

音视频

 



作者:流星泪x
链接:https://www.jianshu.com/p/8ce865c9bbac
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值