library improvements

This commit is contained in:
Nick Payne
2026-02-25 20:26:39 +00:00
parent c4cf27553a
commit 08f0bc8f6c
12 changed files with 171 additions and 112 deletions
+10 -10
View File
@@ -99,11 +99,11 @@ struct AudioTee {
func run() throws {
setupSignalHandlers()
Logger.info("Starting AudioTee...")
AudioTeeLogging.logger.info("Starting AudioTee...")
// Validate chunk duration
guard chunkDuration > 0 && chunkDuration <= 5.0 else {
Logger.error(
AudioTeeLogging.logger.error(
"Invalid chunk duration",
context: ["chunk_duration": String(chunkDuration), "valid_range": "0.0 < duration <= 5.0"])
throw ExitCode.failure
@@ -123,7 +123,7 @@ struct AudioTee {
do {
try audioTapManager.setupAudioTap(with: tapConfig)
} catch AudioTeeError.pidTranslationFailed(let failedPIDs) {
Logger.error(
AudioTeeLogging.logger.error(
"Failed to translate process IDs to audio objects",
context: [
"failed_pids": failedPIDs.map(String.init).joined(separator: ", "),
@@ -131,21 +131,21 @@ struct AudioTee {
])
throw ExitCode.failure
} catch {
Logger.error(
AudioTeeLogging.logger.error(
"Failed to setup audio tap", context: ["error": String(describing: error)])
throw ExitCode.failure
}
guard let deviceID = audioTapManager.getDeviceID() else {
Logger.error("Failed to get device ID from audio tap manager")
AudioTeeLogging.logger.error("Failed to get device ID from audio tap manager")
throw ExitCode.failure
}
let outputHandler = BinaryAudioOutputHandler(flushAfterWrite: flush)
let recorder = AudioRecorder(
let recorder = try AudioRecorder(
deviceID: deviceID, outputHandler: outputHandler, convertToSampleRate: sampleRate,
chunkDuration: chunkDuration)
recorder.startRecording()
try recorder.startRecording()
// Run until the run loop is stopped (by signal handler)
while true {
@@ -155,17 +155,17 @@ struct AudioTee {
}
}
Logger.info("Shutting down...")
AudioTeeLogging.logger.info("Shutting down...")
recorder.stopRecording()
}
private func setupSignalHandlers() {
signal(SIGINT) { _ in
Logger.info("Received SIGINT, initiating graceful shutdown...")
AudioTeeLogging.logger.info("Received SIGINT, initiating graceful shutdown...")
CFRunLoopStop(CFRunLoopGetMain())
}
signal(SIGTERM) { _ in
Logger.info("Received SIGTERM, initiating graceful shutdown...")
AudioTeeLogging.logger.info("Received SIGTERM, initiating graceful shutdown...")
CFRunLoopStop(CFRunLoopGetMain())
}
}
@@ -0,0 +1,32 @@
import AudioTeeCore
import Foundation
/// CLI-specific output handler that writes raw PCM audio to stdout
/// and lifecycle messages to stderr via the logger.
class BinaryAudioOutputHandler: AudioOutputHandler {
private let flushAfterWrite: Bool
init(flushAfterWrite: Bool = false) {
self.flushAfterWrite = flushAfterWrite
}
func handleAudioPacket(_ packet: AudioPacket) {
// Write raw binary audio data directly to stdout
FileHandle.standardOutput.write(packet.data)
if flushAfterWrite {
fflush(stdout)
}
}
func handleMetadata(_ metadata: AudioStreamMetadata) {
AudioTeeLogging.logger.writeMessage(.metadata, data: metadata)
}
func handleStreamStart() {
AudioTeeLogging.logger.writeMessage(.streamStart, data: Optional<String>.none)
}
func handleStreamStop() {
AudioTeeLogging.logger.writeMessage(.streamStop, data: Optional<String>.none)
}
}