【问题标题】:OSX CoreAudio: Getting inNumberFrames in advance - on initialization?OSX CoreAudio:提前获取 inNumberFrames - 初始化?
【发布时间】:2016-03-08 19:07:02
【问题描述】:

我正在尝试用 C 语言编写一个简单的基于单 AU 播放、(几乎)无延迟的跟踪相位声码器原型。它是一个独立程序。我想知道单个渲染回调可以安全承受多少处理负载,所以我更喜欢不使用异步 DSP。

我的概念是只有一个预先确定的值,即 window step,或 hop size抽取因子(不同文献来源中使用的相同术语的不同名称)。这个数字等于inNumberFrames,这在某种程度上取决于设备采样率(还有什么?)。所有其他参数,例如 window sizeFFT size 将根据窗口步长进行设置。这似乎是 keeipng 在一个回调中的所有内容的最简单方法。

在实际渲染开始之前,即在调用AudioOutputUnitStart() 之前,是否有一种安全的方法可以独立于机器并且安全地猜测或查询inNumberFrames

相位声码器算法大多是标准的,非常简单,使用 vDSP 函数进行 FFT,加上自定义相位积分,我没有任何问题。

其他调试信息

此代码在输入回调中监控计时:

static Float64 prev_stime;  //prev. sample time
static UInt64  prev_htime;  //prev. host time        
printf("inBus: %d\tframes: %d\tHtime: %lld\tStime: %7.2lf\n",
       (unsigned int)inBusNumber,
       (unsigned int)inNumberFrames,
       inTimeStamp->mHostTime   - prev_htime,
       inTimeStamp->mSampleTime - prev_stime);
prev_htime = inTimeStamp->mHostTime;
prev_stime = inTimeStamp->mSampleTime;

奇怪的是,参数 inTimeStamp->mSampleTime 实际上显示了渲染帧的数量(参数的名称似乎有些误导)。无论是否在运行时通过 AudioMIDISetup.app 重新设置了另一个采样率,此数字始终为 512,就好像该值已以编程方式硬编码一样。一方面,

inTimeStamp->mHostTime - prev_htime

间隔会根据以数学清晰的方式设置的采样率动态变化。只要采样率值匹配 44100Hz 的倍数,实际渲染就会继续进行。另一方面,48kHz 倍数产生渲染error -10863 ( = kAudioUnitErr_CannotDoInCurrentContext )。我一定错过了一个非常重要的点。

【问题讨论】:

    标签: macos core-audio audiounit


    【解决方案1】:

    帧数通常是采样率乘以缓冲持续时间。有一个音频单元 API 可以请求采样率和首选缓冲区持续时间(例如 44100 和 5.8 毫秒,导致 256 帧),但并非所有操作系统版本上的所有硬件都支持所有请求的缓冲区持续时间或采样率。

    【讨论】:

    • 谢谢。你能给我更多的参考吗?您提到的是哪个 AU API 的哪个版本?我知道 sample rateFloat64(带有 56 位尾数),理论上它允许各种小数率和转换,但这不是我所追求的。我只需要很少的标准费率(44k1 和 48k 的倍数),还需要inNumberFrames,它们是二的幂。我也读过inNumberFrames只能在一定程度上被预测,因为系统可能偶尔会决定这个数字或多或少是几帧,虽然我到目前为止还没有经历过。
    • 它可能关注的对象:请参阅此问题的后续内容,以获得进一步的详细说明和相关答案:stackoverflow.com/questions/36546518/…
    【解决方案2】:

    假设 audioUnit 是一个输入音频单元:

    UInt32 inNumberFrames = 0;
    UInt32 propSize = sizeof(UInt32);
    AudioUnitGetProperty(audioUnit, 
                         kAudioDevicePropertyBufferFrameSize, 
                         kAudioUnitScope_Global, 
                         0, 
                         &inNumberFrames, 
                         &propSize);
    

    【讨论】:

    • 它是一个 kAudioUnitSubType_HALOutput。我会立即检查您的建议是否适合我。谢谢。
    • 它返回预期的数字。由于到目前为止我的大部分代码都被“破解”以满足这一期望,因此我必须用变量重写它,然后检查其他采样频率、主机和硬件设备。如果可行,我会接受你的回答。到目前为止,它指向了良好的方向。
    • 建议的代码 sn-p 似乎总是返回 512 帧,这对于 44k1 SR 似乎没问题。但是,如果我在 AudioMIDI 设置(程序接受)中将 SR 更改为 48k,预期的 inNumberFrames 仍然保持不变(我怀疑它应该),并且回调报告 @987654323 @。在回调中,实际的inNumberFrames 也保持在512,我也怀疑它应该这样做。
    【解决方案3】:

    这个数字等于 inNumberFrames,这在某种程度上取决于设备的采样率(还有什么?)

    这取决于您尝试将其设置为什么。你可以设置它。

    // attempt to set duration
    NSTimeInterval _preferredDuration = ...
    NSError* err;
    [[AVAudioSession sharedInstance]setPreferredIOBufferDuration:_preferredDuration error:&err];
    
    
    // now get the actual duration it uses
    
    NSTimeInterval _actualBufferDuration;
    _actualBufferDuration = [[AVAudioSession sharedInstance] IOBufferDuration];
    

    它会使用一个大约在您设置的首选值附近的值。实际使用的值是基于 2 的幂和当前采样率的时间间隔。

    如果您正在寻找跨设备的一致性,请选择 10 毫秒左右的值。性能最差的现代设备是没有后置摄像头的 iOS iPod touch 16gb。但是,该设备可以毫无问题地进行大约 10 毫秒的回调。在某些设备上,您“可以”将持续时间设置得非常低并获得非常快的回调,但通常它会爆裂,因为在下一次回调发生之前回调中的处理尚未完成。

    【讨论】:

    • 谢谢,但是我不使用AVAudioSession API、iOSCocoa,只使用 OSX CoreAudio,这是一个 C API。所以你的 API 建议对我来说是禁区。我希望我的问题措辞准确。我希望将 OSX 放在标题中是有原因的。我现在必须检查这些很酷的方法是否有它们普通的C 等价物,如果有的话那就太好了。不过还是谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 2021-12-05
    • 2019-09-05
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    相关资源
    最近更新 更多