Объединение AVAudioPCMBuffers - PullRequest
       59

Объединение AVAudioPCMBuffers

1 голос
/ 23 января 2020

Я записываю аудио с помощью AVEngine, используя installTap(onBus:bufferSize:format). Это генерирует AVAudioPCMBuffers, которые я накапливаю. Когда я закончу запись, я хочу объединить их в один AVAudioPCMBuffer, чтобы я мог использовать его с другим кодом, который работает с буферами. (Хотя в некоторых случаях я хочу записать это в файл, в общем случае я этого не делаю.)

Есть ли способ объединить буферы, не опускаясь до уровня Core Audio и не манипулируя AudioBufferList

1 Ответ

0 голосов
/ 02 февраля 2020

Хотелось бы что-нибудь подобное? (Не проверено и жестко запрограммировано для Float данных, но может быть началом)

extension AVAudioPCMBuffer {
    func append(_ buffer: AVAudioPCMBuffer) {
        append(buffer, startingFrame: 0, frameCount: buffer.frameLength)
    }

    func append(_ buffer: AVAudioPCMBuffer, startingFrame: AVAudioFramePosition, frameCount: AVAudioFrameCount) {
        precondition(format == buffer.format, "Format mismatch")
        precondition(startingFrame + AVAudioFramePosition(frameCount) <= AVAudioFramePosition(buffer.frameLength), "Insufficient audio in buffer")
        precondition(frameLength + frameCount <= frameCapacity, "Insufficient space in buffer")

        let dst = floatChannelData!
        let src = buffer.floatChannelData!

        memcpy(dst.pointee.advanced(by: stride * Int(frameLength)),
               src.pointee.advanced(by: stride * Int(startingFrame)),
               Int(frameCount) * stride * MemoryLayout<Float>.size)

        frameLength += frameCount
    }

    convenience init?(concatenating buffers: AVAudioPCMBuffer...) {
        precondition(buffers.count > 0)
        let totalFrames = buffers.reduce(0, { $1.frameLength })
        self.init(pcmFormat: buffers[0].format, frameCapacity: totalFrames)
        buffers.forEach { append($0) }
    }
}
...