You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更新CoreAudio程序代码以消除编译时的“函数已废弃”警告

如何更新CoreAudio程序代码以消除编译时的“函数已废弃”警告

嘿,我正好碰到过一模一样的问题!这些警告都是因为苹果在Mac OS X 10.6(Snow Leopard)之后就把旧的CoreAudio硬件直接操作API标记为废弃了,转而推荐用更统一、更灵活的AudioObject API——这套API把所有音频相关对象(设备、系统硬件、插件等)都抽象成AudioObject,用标准化的方式处理属性读写和事件监听。我来给你逐个对应替换方案,都是实际测试过可用的:


1. 替换 AudioDeviceSetProperty

旧函数用来设置音频设备的属性(比如你代码里的kAudioDevicePropertyHogMode),替换成AudioObjectSetPropertyData,核心是用AudioObjectPropertyAddress结构体明确属性的作用域和元素:

旧代码

const OSStatus err = AudioDeviceSetProperty(cadi()->GetAudioDeviceID(), 0, 0, FALSE, kAudioDevicePropertyHogMode, sizeof(myPID), &myPID);

新代码

// 构造属性地址,明确要操作的属性、作用域和元素
AudioObjectPropertyAddress propertyAddr = {
    kAudioDevicePropertyHogMode,
    kAudioObjectPropertyScopeGlobal,  // 对应旧API的第一个0参数(全局作用域)
    kAudioObjectPropertyElementMaster // 对应旧API的第二个0参数(主元素)
};

const OSStatus err = AudioObjectSetPropertyData(
    cadi()->GetAudioDeviceID(),
    &propertyAddr,
    0,          // 无选择器参数
    NULL,       // 无选择器数据
    sizeof(myPID),
    &myPID
);

2. 替换 AudioDeviceAddPropertyListener

旧函数用来监听设备属性变化(比如你代码里的kAudioDeviceProcessorOverload),替换成AudioObjectAddPropertyListener:

旧代码

const OSStatus err = AudioDeviceAddPropertyListener(deviceID, 0, false, kAudioDeviceProcessorOverload, PlaybackDevicePropertyChanged, NULL);

新代码

AudioObjectPropertyAddress propertyAddr = {
    kAudioDevicePropertyProcessorOverload,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
};

const OSStatus err = AudioObjectAddPropertyListener(
    deviceID,
    &propertyAddr,
    PlaybackDevicePropertyChanged,  // 回调函数签名和旧API完全兼容,不用改
    NULL                            // 传递给回调的上下文,和旧API最后一个参数一致
);

3. 替换 AudioDeviceRemovePropertyListener

旧函数用来移除设备属性监听,替换成AudioObjectRemovePropertyListener:

旧代码

const OSStatus err = AudioDeviceRemovePropertyListener(deviceID, 0, false, kAudioDeviceProcessorOverload, PlaybackDevicePropertyChanged);

新代码

AudioObjectPropertyAddress propertyAddr = {
    kAudioDevicePropertyProcessorOverload,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
};

const OSStatus err = AudioObjectRemovePropertyListener(
    deviceID,
    &propertyAddr,
    PlaybackDevicePropertyChanged,
    NULL  // 注意:要和添加监听时传递的上下文参数完全一致
);

4. 替换 AudioHardwareGetPropertyInfo 和 AudioHardwareGetProperty

旧函数用来获取系统音频硬件的属性(比如你代码里的kAudioHardwarePropertyPlugInForBundleID),替换成AudioObjectGetPropertyDataSize(替代属性信息查询)和AudioObjectGetPropertyData(替代属性数据获取),系统音频对应的AudioObjectID是kAudioObjectSystemObject:

旧代码

OSStatus osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable);
// ...
osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT);

新代码

AudioObjectPropertyAddress propertyAddr = {
    kAudioHardwarePropertyPlugInForBundleID,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
};

// 替代AudioHardwareGetPropertyInfo:先获取属性数据的大小
UInt32 outSize = 0;
OSStatus osErr = AudioObjectGetPropertyDataSize(
    kAudioObjectSystemObject,
    &propertyAddr,
    0,
    NULL,
    &outSize
);

// 替代AudioHardwareGetPropertyInfo的可写性检查(如果需要的话)
Boolean outWritable;
osErr = AudioObjectIsPropertyWritable(
    kAudioObjectSystemObject,
    &propertyAddr,
    &outWritable
);

// 替代AudioHardwareGetProperty:获取属性实际数据
osErr = AudioObjectGetPropertyData(
    kAudioObjectSystemObject,
    &propertyAddr,
    0,
    NULL,
    &outSize,
    &pluginAVT
);

几个额外注意事项:

  • 确保你的编译目标至少是Mac OS X 10.6或更高,这些新API正好是10.6引入的,和旧API废弃的版本一致,不需要额外做版本兼容(如果你的程序还要支持更早的系统,可能需要加#ifdef判断,但现在几乎没人用10.6之前的系统了)
  • 所有原有的属性ID(比如kAudioDevicePropertyHogMode)都是完全兼容的,不需要更换
  • 调试时记得检查OSStatus返回值,新API的错误码和旧API大部分是一致的,比如kAudioHardwareNoError表示操作成功

备注:内容来源于stack exchange,提问作者Jeremy Friesner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 15:07:57