Выделите AudioBufferList с двумя буферами для стереофонического аудиопотока

У меня есть следующий код в C, который выделяет AudioBufferList с соответствующей длиной.

  UInt32 bufferSizeBytes = bufferSizeFrames * sizeof(Float32);
  propertySize = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * mRecordSBD.mChannelsPerFrame);

  mBufferList = (AudioBufferList *) malloc(propertySize);
  mBufferList->mNumberBuffers = mRecordSBD.mChannelsPerFrame;
  for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i)
  {
    mBufferList->mBuffers[i].mNumberChannels = 1;
    mBufferList->mBuffers[i].mDataByteSize = bufferSizeBytes;
    mBufferList->mBuffers[i].mData = malloc(bufferSizeBytes);
  }

Большую часть времени, mChannelsPerFrame равен 2, поэтому приведенный выше код создает два буфера, по одному для каждого канала. Каждый буфер имеет зарезервированные значения памяти bufferSizeBytes,

Как я могу повторить такое же поведение в Swift?

2 ответа

К сожалению, в Swift массив C рассматривается как кортеж, поэтому AudioBufferList.mBuffers импортируется как кортеж с одним AudioBuffer. C позволяет просто получить доступ к соседней памяти с помощью математических указателей (или подстрочный индекс массива в этом случае) для создания структуры переменной длины, Swift не делает.

AudioBufferList просто не очень хорошо переводится в Swift. Apple разрешила эту проблему с помощью нескольких вспомогательных функций и типов. Они создали статическую функцию allocate, которая возвращает UnsafeMutableAudioBufferListPointer, который является специальным типом, где subscript возвращает audioBuffers.

let bufferSizeBytes = MemoryLayout<Float>.size * 1234

var bufferlist = AudioBufferList.allocate(maximumBuffers: 2)
bufferlist[0] = AudioBuffer(mNumberChannels: 1,
                            mDataByteSize: UInt32(bufferSizeBytes),
                            mData: malloc(bufferSizeBytes))
bufferlist[1] = AudioBuffer(mNumberChannels: 1,
                            mDataByteSize: UInt32(bufferSizeBytes),
                            mData: malloc(bufferSizeBytes))

// Free your buffers and the pointer when you're done.
for buffer in bufferlist {
    free(buffer.mData)
}
free(&bufferlist)

Вы можете создать AudioBufferList с 2 буферами для 2 чередующихся потоков, используя Core Audio API:

import AudioUnit
import AVFoundation

var myBufferList = AudioBufferList(
              mNumberBuffers: 2,
              mBuffers: AudioBuffer(
                  mNumberChannels: UInt32(2),
                  mDataByteSize: myBufferSizeBytes,
                  mData: nil) )
Другие вопросы по тегам