Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
406 views
in Technique[技术] by (71.8m points)

ios - Using AudioBufferList with Swift

I have a bridging function in Swift, one of whose arguments in C is AudioBufferList *. In Swift this generates an UnsafePointer<AudioBufferList>. I've manage to deference the pointer by calling audioData[0] (is there a better way?). But I'm struggling with the next 2 tiers down: the .mBuffers array of AudioBuffer's and their void * / UnsafePointer<()> .mData members.

In C it would simply be

Float32 *audioData = (Float 32*)abl->mBuffers[0]->mData;
output = audioData[sampleNum]...

In Swift the first odd thing is that it won't let me access the elements of mBuffers but is perfectly happy when I access it as a property. In other words, this works and even has correct data (for the first member of mBuffers I presume)...

println(abl[0].mBuffers.mNumberChannels)  // But .mBuffers should be an []!

Second, it let's me print out .mData subscripts but the value is always ()

println(abl[0].mBuffers.mData[10])  // Prints '()'

I've tried various casting ops and accessing with multiple indices but to no avail...any ideas?

Here are the C and Swift definitions for AudioBufferList and AudioBuffer for convenience...

// C
struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements
    // ...and a bit more for c++
}


struct AudioBuffer
{
    UInt32  mNumberChannels;
    UInt32  mDataByteSize;
    void*   mData;
};

...

// SWIFT

struct AudioBufferList {
    var mNumberBuffers: UInt32
    var mBuffers: (AudioBuffer)
}

struct AudioBuffer {
    var mNumberChannels: UInt32
    var mDataByteSize: UInt32
    var mData: UnsafePointer<()>
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I found this by accident. Oddly the type ahead was actually working with Swift when it suggested UnsafeMutableAudioBufferListPointer. Which you can initialize with an UnsafeMutablePointer argument. This type is a MutableCollectionType and provides subscript and generator access to the contained Audio Buffers.

For example you can set an ABL to silence with the following code

func renderCallback(ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus {

    let abl = UnsafeMutableAudioBufferListPointer(ioData)

    for buffer in abl {

        memset(buffer.mData, 0, Int(buffer.mDataByteSize))
    }

    return noErr
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...