OSX 上核心音频中的频率漂移

Frequency drift in Core Audio on OSX

我有一个框架音频应用程序,它使用 kAudioUnitSubType_HALOutput 通过 AURenderCallback 播放音频。我正在生成一个简单的纯音只是为了测试一下,但音调会不时明显地改变音调;时而上下浮动,时而变化迅速。它最多可以是 ~500Hz 的几个音调。这是回调:

static OSStatus outputCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags,
                               const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber,
                               UInt32 inNumberFrames, AudioBufferList *ioData) {

    static const float frequency = 1000;
    static const float rate = 48000;
    static float phase = 0;

    SInt16 *buffer = (SInt16 *)ioData->mBuffers[0].mData;

    for (int s = 0; s < inNumberFrames; s++) {
        buffer[s] = (SInt16)(sinf(phase) * INT16_MAX);
        phase += 2.0 * M_PI * frequency / rate;
    }

    return noErr;

}

我知道音频设备会随着时间的推移而漂移(尤其是像内置 IO 这样便宜的设备),但这是 很多漂移 — 它不能用于音乐。有什么想法吗?

Recording http://files.danhalliday.com/Whosebug/audio.png

您永远不会重置 phase,因此它的值会无限增加。由于是以浮点型存储的,存储值的精度会随着值的增加而降低。这可能是您描述的频率变化的原因。

将以下几行添加到 for() 循环的主体中应该可以显着缓解问题:

if (phase > 2.0 * M_PI)
    phase -= 2.0 * M_PI;

phase 的类型从 float 更改为 double 也会有很大帮助。