Files
openless/Sources/OpenLessApp/Audio/BufferingAudioConsumer.swift
T

54 lines
1.4 KiB
Swift

import Foundation
import OpenLessCore
final class BufferingAudioConsumer: AudioConsumer, @unchecked Sendable {
private let lock = NSLock()
private let maxBufferedBytes: Int
private var target: AudioConsumer?
private var bufferedChunks: [Data] = []
private var bufferedByteCount = 0
init(maxBufferedBytes: Int = 320_000) {
self.maxBufferedBytes = maxBufferedBytes
}
func consume(pcmChunk: Data) {
lock.lock()
if let target {
lock.unlock()
target.consume(pcmChunk: pcmChunk)
return
}
bufferedChunks.append(pcmChunk)
bufferedByteCount += pcmChunk.count
while bufferedByteCount > maxBufferedBytes, let first = bufferedChunks.first {
bufferedByteCount -= first.count
bufferedChunks.removeFirst()
}
lock.unlock()
}
func attach(_ target: AudioConsumer) {
lock.lock()
self.target = target
let pending = bufferedChunks
bufferedChunks.removeAll(keepingCapacity: true)
bufferedByteCount = 0
lock.unlock()
for chunk in pending {
target.consume(pcmChunk: chunk)
}
}
func clear() {
lock.lock()
target = nil
bufferedChunks.removeAll(keepingCapacity: false)
bufferedByteCount = 0
lock.unlock()
}
}