我在 Objective C 中有这段代码,运行良好:
list = controller->audioBufferList;
list->mBuffers[0].mDataByteSize = inNumberFrames*kSampleWordSize;
list->mBuffers[1].mDataByteSize = inNumberFrames*kSampleWordSize;
它工作得非常好,它更新了 mBuffers[0] 和 mBuffers[1] 的 mDataByteSize 字段。我尝试在 Swift 中翻译相同的内容,但它不起作用:
public var audioBufferList:UnsafeMutableAudioBufferListPointer
在功能上,
let listPtr = controller.audioBufferList.unsafeMutablePointer
let buffers = UnsafeBufferPointer<AudioBuffer>(start: &listPtr.pointee.mBuffers, count: Int(listPtr.pointee.mNumberBuffers))
for var buf in buffers {
buf.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
NSLog("Data byte size \(buf.mDataByteSize)")
}
for buf in buffers {
NSLog("Data byte size \(buf.mDataByteSize)")
}
mDataByteSize 未更新。第二个 for 循环中读回的 NSLog 指向原始值,而不是更新的值。看来 var buf 是通过复制来引用另一个 buf 的。我如何解决它?这是一个纯粹的 Swift 语言问题,我无法理解。
编辑:正如马丁所指出的,我通过将 for 循环修改为
for i in 0..<Int(listPtr.pointee.mNumberBuffers) {
buffers[i].mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
}
现在可以了。但这进一步激起了我对 Swift 语言的好奇,它是多么不直观,对于使用指针来操作东西的开发人员来说是多么令人恼火。为什么下面的循环会失败? var 缓冲区是否按值复制?
for buf in buffers {
var buffer = buf
buffer.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
}
Or
for var buf in buffers {
buf.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
}
编辑2:哈米什的回答引起了人们对在任何地方使用 listPtr 的有效性的怀疑。我在许多调用中使用了 listPtr,例如:
let status = AudioUnitRender(controller.audioUnit!, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, listPtr)
我现在需要知道哪里可以使用 listPtr,哪里不能!