我在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未更新。 NSLog在第二次读回for循环时指向原始值,而不是更新的值。似乎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)
}
或
for var buf in buffers {
buf.mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
}
编辑2:Hamish的回答使人们怀疑在任何地方使用listPtr的有效性。我在许多电话中都使用了listPtr,例如:
let status = AudioUnitRender(controller.audioUnit!, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, listPtr)
我现在需要知道在哪里可以使用listPtr,在哪里不能使用!
答案 0 :(得分:4)
通话:
let buffers = UnsafeBufferPointer<AudioBuffer>(start: &listPtr.pointee.mBuffers, count: Int(listPtr.pointee.mNumberBuffers))
&listPtr.pointee.mBuffers
产生一个临时指针,该临时指针仅在对UnsafeBufferPointer
的初始化程序的调用期间有效。因此,尝试使用缓冲区指针会导致未定义的行为(在Swift 5.1中为编译器will hopefully warn on such cases)。
相反,您可以直接在UnsafeMutableAudioBufferListPointer
上进行迭代,因为它符合MutableCollection
。
例如:
for index in audioBufferList.indices {
audioBufferList[index].mDataByteSize = inNumberFrames * UInt32(sampleWordSize)
print("Data byte size \(audioBufferList[index].mDataByteSize)")
}
for buffer in audioBufferList {
print("Data byte size \(buffer.mDataByteSize)")
}