我正在尝试从AudioUnit:读取信息
var value = AudioChannelLayoutTag()
var size = UInt32(MemoryLayout<AudioChannelLayoutTag>.size)
let status = AudioUnitGetProperty(audioUnit, kAudioUnitProperty_SupportedChannelLayoutTags, kAudioUnitScope_Global, 0, &value, &size)
它总是让我回想起一个错误:kAudioUnitErr_InvalidElement(错误代码:-10877(
你能给我个建议吗?
kAudioUnitProperty_SupportedChannelLayoutTags
使用kAudioUnitScope_Input
或kAudioUnitScope_Output
的作用域。这就是错误的来源。
如果将kAudioUnitScope_Global
更改为kAudioUnitScope_Input
或kAudioUnitScope_Output
,则代码将按预期工作。但它只会返回音频单元支持的标签数组的第一个元素。
在kAudioUnitProperty_SupportedChannelLayoutTags
上执行AudioUnitGetProperty
时,它会将标记放入具有指定大小的数组中。它还将指定的大小修改为有效缓冲区的大小。
不幸的是,在尝试访问它之前,无法知道标签的数量。因此,我们只能逐步访问它。
以下代码返回音频单元输出所支持的标记数。它尝试首先访问4个元素,然后通过加倍来扩展该数字,直到返回的元素大小小于指定的大小。
func supportedOutputChannelLayoutTags() -> [AudioChannelLayoutTag] {
let elementSize = MemoryLayout<AudioChannelLayoutTag>.size
var elementCount = 4
while true {
var layoutTags = [AudioChannelLayoutTag](repeating: kAudioChannelLayoutTag_Unknown, count: elementCount)
let ioSize = UInt32(elementSize * layoutTags.count)
var returnedIoSize = ioSize
AudioUnitGetProperty(self, kAudioUnitProperty_SupportedChannelLayoutTags, kAudioUnitScope_Output, 0, &layoutTags, &returnedIoSize)
if returnedIoSize != ioSize {
layoutTags.removeLast(Int(ioSize - returnedIoSize) / elementSize)
return layoutTags
}
//Guard against cases where there is no tags.
//The `AudioUnitGetProperty` will not modify &returnedIoSize if no tag is copied.
if layoutTags.first == kAudioChannelLayoutTag_Unknown { return [] }
elementCount *= 2
}
}