Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说Audio Unit: iOS中最底层最强大音频控制API,希望能够帮助你!!!。
以下概念是文中常用的词语,因为其含义一般直接用英文表达, 一般不需中文翻译,可将其理解为固定名词词组.
注意每个element还可能具有input scope与output scope.
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仅在高性能,专业处理声音的需求下使用才有意义.
使用场景
功能 |
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 |
iOS有一个用于直接处理audio units的API,另一个用于处理audio processing graphs,可以同时使用这两种API. 然而这两种API中有一部分功能是相同的,如下:
C++音视频学习资料免费获取方法:关注音视频开发T哥,点击「链接」即可免费获取2023年最新C++音视频开发进阶独家免费学习大礼包!
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组成.
上图展示了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与回调函数,以用来解决任意音频处理方法。
当我们将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输入端之前.如图,以下是重新配置的步骤
上面1,2,4步使用AUGraph*开头的函数,都会被添加到graph的任务执行列表中.通过调用AUGraphUpdate执行这些未开始任务.如果成功返回,则graph已经被动态重新配置并且iPod EQ也已经就位正在处理音频数据.
在audio processing graph可以使用类似生产者消费者模式,消费者在需要更多音频数据时通知生产者。请求音频数据流的方向与音频流提供的方向正好相反.
对一组音频数据的每个请求称为渲染调用(render call),也称为拉流(pull)。该图表示拉流为灰色“控制流”箭头。拉流请求的数据更恰当地称为一组音频样本帧(audio sample frames)。反过来,响应拉流而提供的一组音频样本帧被称为slice.提供slice的代码称为渲染回调函数( render callback function).
为了从本地文件或内存中将音频传给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 *
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类型表示未压缩的音频数据,
在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
你还可以配置一些其他功能,如采样率为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 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 |
原文链接:Audio Unit: iOS中最底层最强大音频控制API
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。