构建 Audio Unit 的流程

构建AudioUnit详解

构建 Audio Unit 的流程

iOS 有一个用于直接处理 audio units 的 API,另一个用于处理 audio processing graphs,可以同时使用这两种 API。然而这两种 API 中有一部分功能是相同的:

  • 获取 audio units 的动态可链接库的引用。
  • 实例化 audio units。
  • 连接 audio units 并注册回调函数。
  • 启动和停止音频流。

指定 Audio Unit 的类型

// Creating an audio component description to identify an audio unit
AudioComponentDescription ioUnitDescription;
 
ioUnitDescription.componentType          = kAudioUnitType_Output;
ioUnitDescription.componentSubType       = kAudioUnitSubType_RemoteIO;
ioUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
ioUnitDescription.componentFlags         = 0;
ioUnitDescription.componentFlagsMask     = 0;

创建 Audio Unit

使用 audio unit API — AudioComponent 创建:

// Obtaining an audio unit instance using the audio unit API
AudioComponent foundIoUnitReference = AudioComponentFindNext (
                                          NULL,
                                          &ioUnitDescription
                                      );
AudioUnit ioUnitInstance;
AudioComponentInstanceNew (
    foundIoUnitReference,
    &ioUnitInstance
);

AudioComponentFindNext:第一个参数设置为 NULL 表示使用系统定义的顺序查找第一个匹配的 audio unit;如果你将上一个使用的 audio unit 引用传给该参数,则该函数将继续寻找下一个与之描述匹配的audio unit。

AudioComponentInstanceNew 的第二个参数类型是 AudioComponentInstance。AudioUnit 实际上就是 AudioComponentInstance,在 AudioComponent 类中有定义:

typedef AudioComponentInstance AudioUnit;

还可以使用 audio processing graph API 初始化 audio unit,即通过 AUNode 创建 Audio Unit,分为 3 步:

  1. 创建一个 AUGraph。
  2. 获取一个 AUNode。
  3. 获取一个 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 Unit 的属性

Audio Unit 实际上就是一个 AudioComponentInstance 实例对象,一个 AudioUnit 由 scope 和 element 组成。

在这里插入图片描述

scope 是 Audio Unit 内部的编程上下文,其定义为枚举值:

CF_ENUM(AudioUnitScope) {
    kAudioUnitScope_Global      = 0,
    kAudioUnitScope_Input       = 1,
    kAudioUnitScope_Output      = 2,
    kAudioUnitScope_Group       = 3,
    kAudioUnitScope_Part        = 4,
    kAudioUnitScope_Note        = 5,
    kAudioUnitScope_Layer       = 6,
    kAudioUnitScope_LayerItem   = 7
};

主要使用到的输入 kAudioUnitScope_Input 和输出 kAudioUnitScope_Output。参考 Figure1-2,Input scope 表示里面的所有的 element 都需要一个输入;Output scope 表示里面的所有的 element 都会输出到某个地方;Global scope 作为整体应用于 Audio Unit 并且不与任何特定音频流相关联,它只有一个 element,用来配置一些和输入输出无关的属性。

术语 element 和 bus 在 Audio Unit 中是一个含义。当 Element 是 Input/Output scope 的一部分时,它类似于物理音频设备中的信号总线。在强调信号流时使用 bus,在强调音频单元的特定功能时使用 element。

使用 scope 和 element 来设置 Audio Unit 的属性,函数原型为:

AudioUnitSetProperty( AudioUnit               inUnit,
											AudioUnitPropertyID     inID,
                      AudioUnitScope          inScope,
                      AudioUnitElement        inElement,
                      const void * __nullable inData,
                      UInt32                  inDataSize
);

各参数意义:

  • AudioUnitPropertyID:设置属性名称。有以下枚举值:

    • kAudioOutputUnitProperty_EnableIO:用于在 I/O unit 上启用或禁用输入或输出。默认情况下,输出已启用但输入已禁用。
    • kAudioUnitProperty_ElementCount:elements 的数量。
    • kAudioUnitProperty_MaximumFramesPerSlice:为了指定音频数据的最大帧数,音频单元应准备在响应渲染调用时生成。对于大多数音频单元,在大多数情况下,必须按照参考文档中所述设置此属性。如果不这样做,当屏幕锁定时,音频将停止。
    • kAudioUnitProperty_StreamFormat:指定特定 audio unit 输入或输出总线的音频流数据格式。
  • AudioUnitScope:AudioUnit 的 Scope,主要用于输入输出范围。

  • AudioUnitElement:AudioUnit 的 Element,默认用 1 表示输入总线,用 1 表示输出总线。

  • inData:输入值。

  • inDataSize:输入值的长度。

大多数属性只能在 audio unit 没有初始化时指定,但是某些特定属性可以在 audio unit 运行时设置,如 kAUVoiceIOProperty_MuteOutput 静音功能。

要测试属性的可用性,访问其值以及监视其值的更改,可以使用以下函数:

  • AudioUnitGetPropertyInfo:发现属性是否可用;如果是,可以获得其值的数据大小,以及是否可以更改该值。
  • AudioUnitGetProperty、AudioUnitSetProperty:获取、设置一个属性值,可以在 Audio Unit 运行时使用。
  • AudioUnitAddPropertyListener、AudioUnitRemovePropertyListenerWithUserData:添加或删除用于监控属性值更改的回调函数。

函数实例:

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)
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值