Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnsafeMutableAudioBufferListPointer allocation before calling AudioObjectGetPropertyData

I've been trying to use Apple's CoreAudio from swift. I found many examples on how to enumerate streams and channels on a device. However, all of them seem to use incorrect size when calling UnsafeMutablePointer<AudioBufferList>.allocate().

They first request property data size, which returns the number of bytes. Then they use this number of bytes to allocate an (unsafe) AudioBufferList of that size (using the number of bytes as the size of the list!).

Please see my comments inline below:

var address = AudioObjectPropertyAddress(
    mSelector:AudioObjectPropertySelector(kAudioDevicePropertyStreamConfiguration),
    mScope:AudioObjectPropertyScope(kAudioDevicePropertyScopeInput),
    mElement:0)

var propsize = UInt32(0);
var result:OSStatus = AudioObjectGetPropertyDataSize(self.id, &address, 0, nil, &propsize);
if (result != 0) {
    return false;
}

// ABOVE: propsize is set to number of bytes that property data contains, typical number are 8 (no streams), 24 (1 stream, 2 interleaved channels)
// BELOW: propsize is used for AudioBufferList capacity (in number of buffers!)

let bufferList = UnsafeMutablePointer<AudioBufferList>.allocate(capacity:Int(propsize))
result = AudioObjectGetPropertyData(self.id, &address, 0, nil, &propsize, bufferList);
if (result != 0) {
    return false
}

let buffers = UnsafeMutableAudioBufferListPointer(bufferList)
for bufferNum in 0..<buffers.count {
    if buffers[bufferNum].mNumberChannels > 0 {
        return true
    }
}

This works all of the time, because it allocates much more memory than needed for UnsafeMutablePointer<AudioBufferList>, but this is obviously wrong.

I've been searching for a way to correctly allocate UnsafeMutablePointer<AudioBufferList> from the number of bytes that is returned by AudioObjectGetPropertyDataSize(), but I cannot find anything for the whole day. Please help ;)

like image 904
akuz Avatar asked Jun 23 '26 17:06

akuz


1 Answers

to correctly allocate UnsafeMutablePointer<AudioBufferList> from the number of bytes that is returned by AudioObjectGetPropertyDataSize()

You should not allocate UnsafeMutablePointer<AudioBufferList>, but allocate raw bytes of the exact size and cast it to UnsafeMutablePointer<AudioBufferList>.

Some thing like this:

        let propData = UnsafeMutableRawPointer.allocate(byteCount: Int(propsize), alignment: MemoryLayout<AudioBufferList>.alignment)
        result = AudioObjectGetPropertyData(self.id, &address, 0, nil, &propsize, propData);
        if (result != 0) {
            return false
        }
        let bufferList = propData.assumingMemoryBound(to: AudioBufferList.self)
like image 141
OOPer Avatar answered Jun 25 '26 11:06

OOPer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!