Swift 3 中未调用 AudioObjectAddPropertyListenerBlock

AudioObjectAddPropertyListenerBlock not called in Swift 3

我想使用Swift观察音频设备参数的变化 3.我查找了一些信息并找到了这段代码。在我的视图模型中,我设置了一个侦听器块,结果状态为 0(成功):

    override func viewDidLoad() {
        super.viewDidLoad()



        addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
                         onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
                         forPropertyAddress: AudioObjectPropertyAddress(
                            mSelector: kAudioDevicePropertyVolumeScalar,
                            mScope: kAudioObjectPropertyScopeGlobal,
                            mElement: kAudioObjectPropertyElementMaster))

    }

    // Utility function to simplify adding listener blocks:
    func addListenerBlock( listenerBlock: @escaping AudioObjectPropertyListenerBlock, onAudioObjectID: AudioObjectID, forPropertyAddress: AudioObjectPropertyAddress) {
        var forPropertyAddress = forPropertyAddress

let status = AudioObjectAddPropertyListenerBlock(onAudioObjectID, &forPropertyAddress, nil, listenerBlock)
        print(status)
    }


    func audioObjectPropertyListenerBlock (numberAddresses: UInt32, addresses: UnsafePointer<AudioObjectPropertyAddress>) {

        var index: UInt32 = 0
        while index < numberAddresses {
            let address: AudioObjectPropertyAddress = addresses[index]
            switch address.mSelector {
            case kAudioHardwarePropertyDefaultOutputDevice:

                let deviceID = getDefaultAudioOutputDevice()
                print("kAudioHardwarePropertyDefaultOutputDevice: \(deviceID)")

            default:

                print("We didn't expect this!")

            }
            index += 1
        }
    }
        // Utility function to get default audio output device:
        func getDefaultAudioOutputDevice () -> AudioObjectID {

            var devicePropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster)
            var deviceID: AudioObjectID = 0
            var dataSize = UInt32(truncatingBitPattern: MemoryLayout<AudioDeviceID>.size)
            let systemObjectID = AudioObjectID(bitPattern: kAudioObjectSystemObject)
            if (kAudioHardwareNoError != AudioObjectGetPropertyData(systemObjectID, &devicePropertyAddress, 0, nil, &dataSize, &deviceID)) { return 0 }
            return deviceID
    }

然而,即使 OSStatus 为 0 并且添加了侦听器,当我更改参数(在本例中为输出音量)时也不会调用它。我在我的 audioObjectPropertyListenerBlock 中设置了一个断点,但我的应用程序从未到达那里。我错过了什么?

问题出在这里:

addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
               onAudioObjectID: AudioObjectID(bitPattern: kAudioObjectSystemObject),
                forPropertyAddress: AudioObjectPropertyAddress(
                         mSelector: kAudioDevicePropertyVolumeScalar,
                            mScope: kAudioObjectPropertyScopeGlobal,
                        mElement: kAudioObjectPropertyElementMaster))
  1. onAudioObjectID 应该是默认输出设备:getDefaultAudioOutputDevice()(这些 int-ly 类型的 API 令人困惑)
  2. mScope应该是kAudioObjectPropertyScopeOutput,而
  3. mElement应该是1或2。(至少我的输出设备没有master元素!)

总计:

addListenerBlock(listenerBlock: audioObjectPropertyListenerBlock,
                 onAudioObjectID: getDefaultAudioOutputDevice(),
                 forPropertyAddress: AudioObjectPropertyAddress(
                    mSelector: kAudioDevicePropertyVolumeScalar,
                    mScope: kAudioObjectPropertyScopeOutput,
                    mElement: 1))

进行这些更改后,当左声道输出音量更改时将调用您的侦听器块。

不过,我不确定您要在侦听器块中做什么,因为 mSelector 始终是您请求的 kAudioDevicePropertyVolumeScalar,永远不会 kAudioObjectSystemObject.