这可能有点棘手,因为某些音频设备支持主通道,但大多数不支持,因此音量将是每个通道的属性。根据您需要执行的操作,您可以仅观察一个通道,并假设设备支持的所有其他通道具有相同的音量。无论您想要观看多少个频道,您都可以通过为相关 AudioObject 注册属性侦听器来观察音量:
// Some devices (but not many) support a master channel
AudioObjectPropertyAddress propertyAddress = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
if(AudioObjectHasProperty(deviceID, &propertyAddress)) {
OSStatus result = AudioObjectAddPropertyListener(deviceID, &propertyAddress, myAudioObjectPropertyListenerProc, self);
// Error handling omitted
}
else {
// Typically the L and R channels are 1 and 2 respectively, but could be different
propertyAddress.mElement = 1;
OSStatus result = AudioObjectAddPropertyListener(deviceID, &propertyAddress, myAudioObjectPropertyListenerProc, self);
// Error handling omitted
propertyAddress.mElement = 2;
result = AudioObjectAddPropertyListener(deviceID, &propertyAddress, myAudioObjectPropertyListenerProc, self);
// Error handling omitted
}
你的监听器过程应该是这样的:
static OSStatus
myAudioObjectPropertyListenerProc(AudioObjectID inObjectID,
UInt32 inNumberAddresses,
const AudioObjectPropertyAddress inAddresses[],
void *inClientData)
{
for(UInt32 addressIndex = 0; addressIndex < inNumberAddresses; ++addressIndex) {
AudioObjectPropertyAddress currentAddress = inAddresses[addressIndex];
switch(currentAddress.mSelector) {
case kAudioDevicePropertyVolumeScalar:
{
Float32 volume = 0;
UInt32 dataSize = sizeof(volume);
OSStatus result = AudioObjectGetPropertyData(inObjectID, ¤tAddress, 0, NULL, &dataSize, &volume);
if(kAudioHardwareNoError != result) {
// Handle the error
continue;
}
// Process the volume change
break;
}
}
}
}