使用 Core Audio 的代码能否在 iOS 和 macOS 之间兼容?

Can code using Core Audio be compatible across iOS & macOS?

Core Audio 是 iOS 和 macOS 的音频框架。从 Apple's own documentation,我可以看出实现上存在差异。最值得注意的似乎是示例格式(iOS 的固定点与 macOS 的 32 位浮点数)并且 iOS 不支持 Core Audio 的所有方面。

当编写代码来实现两个平台都支持的东西时,是否可以编写一次代码并真正将其移植过来?如果答案是"Yes, but only in certain aspects",请多解释一下。

我们以现场音频合成为例。我想打开一个音频输出流并使用回调方法将样本放入输出缓冲区。我知道这可以在 iOS 和 macOS 上完成,但是当我查找库时,它们似乎并不支持两者。这些库是否真的支持这两种平台,或者是否有根本原因阻止了这一点?

例如:

iOS 上的规范采样格式现在也是立体声浮点 32。

MacOS 支持自定义 v3 和 v2 音频单元,而 iOS 支持自定义 v3 音频单元,但仅系统提供 v2 音频单元。

AVAudioEngine 和朋友们将大部分核心音频 C API 包装在 Swift/ObjC 中,我相信即使有平台差异也很少。我建议先尝试 AVAudioEngine,如果它不能满足您的需求,则使用 C API。

大部分 C API 是跨平台的,但有些区域仅在 macOS 或 iOS 上受支持。您可以查看 headers 以了解差异。例如,这里是输出音频单元的定义 sub-types(删除了文档)。

#if !TARGET_OS_IPHONE

CF_ENUM(UInt32) {
    kAudioUnitSubType_HALOutput             = 'ahal',
    kAudioUnitSubType_DefaultOutput         = 'def ',
    kAudioUnitSubType_SystemOutput          = 'sys ',
};

#else

CF_ENUM(UInt32) {
    kAudioUnitSubType_RemoteIO              = 'rioc',
};

#endif

如果要编写 cross-platform 包装器,则必须围绕平台细节使用预处理器指令。这是一个 cross-platform 函数,它使用特定平台 sub-types 为输出音频单元创建 AudioComponentDescription。

AudioComponentDescription outputDescription() {

    AudioComponentDescription description;
    description.componentType = kAudioUnitType_Output;
    description.componentManufacturer = kAudioUnitManufacturer_Apple;
    description.componentFlags = 0;
    description.componentFlagsMask = 0;

#if TARGET_OS_IPHONE
    description.componentSubType = kAudioUnitSubType_RemoteIO;
#else
    description.componentSubType = kAudioUnitSubType_DefaultOutput;
#endif

    return description;
}

还有一些其他音频单元仅在 iOS 或 macOS 上受支持,与管理 "system" 级音频交互的 API 完全不同。 MacOS 使用 C API,而 iOS 有 AVAudioSession。

我确定我遗漏了一些东西:)