Распределение UnsafeMutableAudioBufferListPointer перед вызовом AudioObjectGetPropertyData - PullRequest
1 голос
/ 21 марта 2020

Я пытался использовать Apple CoreAudio от swift. Я нашел много примеров того, как перечислять потоки и каналы на устройстве. Однако все они, кажется, используют неправильный размер при вызове UnsafeMutablePointer<AudioBufferList>.allocate().

. Сначала они запрашивают размер данных свойства, который возвращает количество байтов. Затем они используют это количество байтов для выделения (небезопасных) AudioBufferList такого размера (используя количество байтов в качестве размера списка!).

Пожалуйста, смотрите мои комментарии, встроенные ниже:

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
    }
}

Это работает все время, потому что оно выделяет гораздо больше памяти, чем необходимо для UnsafeMutablePointer<AudioBufferList>, но это явно неправильно.

Я искал способ правильно распределить UnsafeMutablePointer<AudioBufferList> из числа байтов, возвращаемых AudioObjectGetPropertyDataSize(), но я не могу ничего найти за весь день. Пожалуйста, помогите;)

1 Ответ

1 голос
/ 22 марта 2020

для правильного выделения UnsafeMutablePointer<AudioBufferList> из числа байтов, которое возвращается AudioObjectGetPropertyDataSize()

Вы не должны выделять UnsafeMutablePointer<AudioBufferList>, но выделять необработанные байтов точного размера и приведите к UnsafeMutablePointer<AudioBufferList>.

Примерно так:

        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)
...