import AudioTeeCore import Foundation /// CLI-specific output handler that writes raw PCM audio to a file descriptor /// (stdout by default) and lifecycle messages to stderr via the logger. /// /// `source` tags every stderr message so a consumer running two tracks at /// once (e.g. system audio + microphone, each on its own fd) can tell which /// track a given metadata/lifecycle message belongs to. class BinaryAudioOutputHandler: AudioOutputHandler { private let fd: Int32 private let source: String init(fd: Int32 = STDOUT_FILENO, source: String = "audio") { self.fd = fd self.source = source } func handleAudioData(_ pointer: UnsafeRawPointer, count: Int) { var written = 0 while written < count { let result = write(fd, pointer.advanced(by: written), count - written) if result >= 0 { written += result } else if errno == EINTR { continue } else { break // EPIPE, EIO, etc — consumer gone or real error } } } func handleMetadata(_ metadata: AudioStreamMetadata) { let taggedMetadata = AudioStreamMetadata( sampleRate: metadata.sampleRate, channelsPerFrame: metadata.channelsPerFrame, bitsPerChannel: metadata.bitsPerChannel, isFloat: metadata.isFloat, captureMode: source, deviceName: metadata.deviceName, deviceUID: metadata.deviceUID, encoding: metadata.encoding ) AudioTeeLogging.logger.writeMessage(.metadata, data: taggedMetadata) } func handleStreamStart() { AudioTeeLogging.logger.writeMessage(.streamStart, data: source) } func handleStreamStop() { AudioTeeLogging.logger.writeMessage(.streamStop, data: source) } }