You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
29 lines
1.0 KiB
29 lines
1.0 KiB
import os
|
|
|
|
/// Distributes one producer's audio to several feeds (one per route).
|
|
///
|
|
/// `push` may run on a real-time thread: it only try-locks and otherwise uses the last known list.
|
|
public final class AudioFanout: @unchecked Sendable {
|
|
private let feeds = OSAllocatedUnfairLock<[AudioFeed]>(initialState: [])
|
|
private var cached: [AudioFeed] = [] // producer thread only
|
|
|
|
public init() {}
|
|
|
|
public func add(_ feed: AudioFeed) {
|
|
feeds.withLock { $0.append(feed) }
|
|
}
|
|
|
|
public func remove(_ feed: AudioFeed) {
|
|
feeds.withLock { $0.removeAll { $0 === feed } }
|
|
}
|
|
|
|
public var isEmpty: Bool { feeds.withLock { $0.isEmpty } }
|
|
|
|
public func push(planar data: UnsafePointer<Float>, channelStride: Int, channels: Int, frames: Int, sampleRate: Double) {
|
|
if let current = feeds.withLockIfAvailable({ $0 }) { cached = current }
|
|
for feed in cached {
|
|
feed.push(planar: data, channelStride: channelStride, channels: channels, frames: frames, sampleRate: sampleRate)
|
|
}
|
|
}
|
|
}
|