3

我试图设置一个音频单元来渲染音乐(而不是音频队列..这对我的目的来说太不透明了).. iOS 没有这个属性kAudioDevicePropertyBufferFrameSize.. 知道如何获得这个值来设置我的 IO 单元的缓冲区大小?

我发现这篇文章很有趣..它询问了使用音频会话属性的组合kAudioSessionProperty_CurrentHardwareIOBufferDurationkAudioSessionProperty_CurrentHardwareOutputLatency确定该值的可能性..但是没有答案..有什么想法吗?

4

2 回答 2

5

您可以使用该kAudioSessionProperty_CurrentHardwareIOBufferDuration属性,它以秒为单位表示缓冲区大小。将其乘以您从中获得的采样率,kAudioSessionProperty_CurrentHardwareSampleRate以获得您应该缓冲的样本数。

生成的缓冲区大小应该是 2 的倍数。我相信 512 或 4096 是您可能得到的,但您应该始终基于从AudioSessionGetProperty.

例子:

Float64 sampleRate;
UInt32 propSize = sizeof(Float64);
AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, 
                        &propSize,
                        &sampleRate);

Float32 bufferDuration;
propSize = sizeof(Float32);
AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, 
                        &propSize,
                        &bufferDuration);

UInt32 bufferLengthInFrames = sampleRate * bufferDuration;

下一步是找出您要发送音频的设备的输入流格式。根据您的描述,我假设您正在以编程方式生成音频以发送到扬声器。此代码假定您unit正在AudioUnit向其发送音频,无论是 RemoteIO 还是效果音频单元之类的东西。

AudioStreamBasicDescription inputASBD;
UInt32 propSize = sizeof(AudioStreamBasicDescription);
AudioUnitGetProperty(unit,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Input,
                     0,
                     &inputASBD,
                     &propSize);

在此之后,inputASBD.mFormatFlags将是对应于所unit期望的音频流格式的位字段。最有可能的两组标志被命名为kAudioFormatFlagsCanonicalkAudioFormatFlagsAudioUnitCanonical。这两个具有相应的样本类型AudioSampleTypeAudioUnitSampleType您可以根据这些样本类型进行尺寸计算。

顺便说一句,AudioSampleType通常表示来自麦克风或发往扬声器AudioUnitSampleType的样本,而通常表示打算处理的样本(例如,由音频单元处理)。目前在 iOS 上,AudioSampleType是一个 SInt16 并且AudioUnitSampleType是存储在一个 SInt32 容器中的固定 8.24 数字。这是 Core Audio 邮件列表上的一篇文章,解释了这种设计选择

我之所以不愿说“只使用 Float32,它会起作用”之类的话,是因为如果 Apple 愿意,流的实际位表示可能会发生变化。

于 2012-10-31T20:24:31.297 回答
1

音频单元本身决定实际缓冲区大小,因此应用程序的音频单元回调必须能够处理给它的任何合理大小。您可以建议并轮询 kAudioSessionProperty_CurrentHardwareIOBufferDuration 属性,但请注意,当您的应用程序运行时(尤其是在屏幕锁定或通话中断等期间),此值可能超出应用程序的控制范围。

于 2012-10-31T22:55:05.683 回答