给定结构的访问元素UnsafeMutablePointer

时间:2018-03-02 20:12:24

标签: swift core-audio audiotoolbox

在C中,我有以下代码来分配具有适当大小的AudioBufferList,然后用相关数据填充它。

AudioObjectPropertyScope scope = mIsInput ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
AudioObjectPropertyAddress address = { kAudioDevicePropertyStreamConfiguration, scope, 0 };
UInt32 propertySize;
__Verify_noErr(
  AudioObjectGetPropertyDataSize(mID, &address, 0, NULL, &propertySize)
);
AudioBufferList *bufferList = (AudioBufferList *) malloc(propertySize);
__Verify_noErr(
  AudioObjectGetPropertyData(mID, &address, 0, NULL, &propertySize, bufferList)
);

然后,我可以访问struct element:

UInt32 result { 0 };
for(UInt32 i = 0; i < bufferList->mNumberBuffers; ++i)
{
  result += bufferList->mBuffers[i].mNumberChannels;
}
free(bufferList)

我如何在Swift中复制此行为,因为我使用相同的框架,即AudioToolbox?

我尝试过以下操作,但无法访问mNumberBuffers

let scope: AudioObjectPropertyScope = scope ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioDevicePropertyStreamConfiguration, mScope: scope, mElement: 0)
var size: UInt32 = 0
CheckError(
  AudioObjectGetPropertyDataSize(mID, &address, 0, nil, &size),
  "Couldn't get stream configuration data size."
)
var bufferList = UnsafeMutableRawPointer.allocate(bytes: Int(size), alignedTo: MemoryLayout<AudioBufferList>.alignment).assumingMemoryBound(to: AudioBufferList.self)
CheckError(
  AudioObjectGetPropertyData(mID, &address, 0, nil, &size, bufferList),
  "Couldn't get device's stream configuration"
)

1 个答案:

答案 0 :(得分:1)

您可以像这样创建一个AudioBufferList:

import AudioUnit
import AVFoundation

var myBufferList = AudioBufferList(
              mNumberBuffers: 2,
              mBuffers: AudioBuffer(
                  mNumberChannels: UInt32(2),
                  mDataByteSize: 2048,
                  mData: nil) )

当递交具有未知数量缓冲区的bufferList时,您可以获得缓冲区的数量和样本数据,如下所示:

let myBufferListPtr = UnsafeMutableAudioBufferListPointer(myBufferList)
let numBuffers = myBufferListPtr.count
if (numBuffers > 0) {
        let buffer : AudioBuffer = myBufferListPtr[0]
        let bufferDataPointer = UnsafeMutableRawPointer(buffer.mData)
        if let dataPtr = bufferDataPointer {
            dataPtr.assumingMemoryBound(to: Float.self)[ i ] = x
            ...

我的源代码示例的其余部分位于GitHub上:https://gist.github.com/hotpaw2/ba815fc23b5d642705f2b1dedfaf0107