【问题标题】:kAudioDevicePropertyBufferFrameSize replacement for iOSiOS 的 kAudioDevicePropertyBufferFrameSize 替换
【发布时间】:2012-10-31 12:03:46
【问题描述】:

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

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

【问题讨论】:

    标签: ios core-audio audio-streaming latency


    【解决方案1】:

    您可以使用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 数字。 Here's a post on the Core Audio mailing list explaining this design choice

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

    【讨论】:

    • 所以我假设bufferSizeBytes 将等于sampleRate * bufferDuration * sizeof(Float32)(假设单个样本值4 个字节)?还有另一件事我有点模糊,但你能说bufferLengthInSamples = bufferLengthInFrames(即使我们正在处理立体声音频,即 1 帧 = 2 个样本)
    • 好点,将其称为 bufferLengthInFrames 会更正确。 RE:以字节为单位的样本大小,您不应假设它们将采用什么格式。不同的音频单元将具有不同的兼容输入/输出格式。我将更新我的答案以反映下一步。
    • 第一个弃用部分的现代方法是使用 AVAudioSession: [[AVAudioSession sharedInstance] sampleRate] * [[AVAudioSession sharedInstance] IOBufferDuration];
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 2013-02-01
      • 1970-01-01
      相关资源
      最近更新 更多