potential split between CLI and core library

This commit is contained in:
Nick Payne
2025-08-19 08:51:14 +01:00
parent a311cc583f
commit b7455d26d1
20 changed files with 74 additions and 8 deletions
+32 -2
View File
@@ -8,7 +8,37 @@ let package = Package(
platforms: [ platforms: [
.macOS("14.2") .macOS("14.2")
], ],
products: [
// Library that can be imported by other packages
.library(
name: "AudioTeeCore",
targets: ["AudioTeeCore"]
),
// CLI executable
.executable(
name: "audiotee",
targets: ["AudioTeeCLI"]
)
],
targets: [ targets: [
.executableTarget(name: "audiotee") // Core library with all business logic
.target(
name: "AudioTeeCore",
path: "Sources/AudioTeeCore"
),
// CLI executable that uses the library
.executableTarget(
name: "AudioTeeCLI",
dependencies: ["AudioTeeCore"],
path: "Sources/AudioTeeCLI"
),
// Tests for the library
.testTarget(
name: "AudioTeeCoreTests",
dependencies: ["AudioTeeCore"],
path: "Tests/AudioTeeCoreTests"
)
] ]
) )
@@ -1,3 +1,4 @@
import AudioTeeCore
import CoreAudio import CoreAudio
import Foundation import Foundation
@@ -1,3 +1,4 @@
import AudioTeeCore
import AudioToolbox import AudioToolbox
import Foundation import Foundation
@@ -10,7 +10,7 @@ public class AudioRecorder {
private var outputHandler: AudioOutputHandler private var outputHandler: AudioOutputHandler
private var converter: AudioFormatConverter? private var converter: AudioFormatConverter?
init( public init(
deviceID: AudioObjectID, outputHandler: AudioOutputHandler, convertToSampleRate: Double? = nil, deviceID: AudioObjectID, outputHandler: AudioOutputHandler, convertToSampleRate: Double? = nil,
chunkDuration: Double = 0.2 chunkDuration: Double = 0.2
) { ) {
@@ -51,7 +51,7 @@ public class AudioRecorder {
} }
} }
func startRecording() { public func startRecording() {
Logger.debug("Starting audio recording") Logger.debug("Starting audio recording")
// Log format info and send metadata for final format // Log format info and send metadata for final format
@@ -112,7 +112,7 @@ public class AudioRecorder {
return noErr return noErr
} }
func stopRecording() { public func stopRecording() {
processAudioBuffer() processAudioBuffer()
outputHandler.handleStreamStop() outputHandler.handleStreamStop()
cleanupIOProc() cleanupIOProc()
@@ -3,10 +3,12 @@ import AudioToolbox
import CoreAudio import CoreAudio
import Foundation import Foundation
class AudioTapManager { public class AudioTapManager {
private var tapID: AudioObjectID? private var tapID: AudioObjectID?
private var deviceID: AudioObjectID? private var deviceID: AudioObjectID?
public init() {}
deinit { deinit {
Logger.debug("Cleaning up audio tap manager") Logger.debug("Cleaning up audio tap manager")
@@ -22,7 +24,7 @@ class AudioTapManager {
} }
/// Sets up the audio tap and aggregate device /// Sets up the audio tap and aggregate device
func setupAudioTap(with config: TapConfiguration) throws { public func setupAudioTap(with config: TapConfiguration) throws {
Logger.debug("Setting up audio tap manager") Logger.debug("Setting up audio tap manager")
tapID = try createSystemAudioTap(with: config) tapID = try createSystemAudioTap(with: config)
@@ -38,7 +40,7 @@ class AudioTapManager {
} }
/// Returns the aggregate device ID for recording /// Returns the aggregate device ID for recording
func getDeviceID() -> AudioObjectID? { public func getDeviceID() -> AudioObjectID? {
return deviceID return deviceID
} }
@@ -1,6 +1,8 @@
import Foundation import Foundation
public class BinaryAudioOutputHandler: AudioOutputHandler { public class BinaryAudioOutputHandler: AudioOutputHandler {
public init() {}
public func handleAudioPacket(_ packet: AudioPacket) { public func handleAudioPacket(_ packet: AudioPacket) {
// TODO: should we use a DispatchQueue instead of writing directly? // TODO: should we use a DispatchQueue instead of writing directly?
// Write raw binary audio data directly to stdout // Write raw binary audio data directly to stdout
@@ -0,0 +1,30 @@
import XCTest
@testable import AudioTeeCore
final class AudioPacketTests: XCTestCase {
func testPacketCreation() {
let timestamp = Date()
let duration = 1.0
let data = Data([0x01, 0x02, 0x03, 0x04])
let packet = AudioPacket(
timestamp: timestamp,
duration: duration,
data: data
)
XCTAssertEqual(packet.timestamp, timestamp)
XCTAssertEqual(packet.duration, duration)
XCTAssertEqual(packet.data, data)
}
func testPacketDataSize() {
let packet = AudioPacket(
timestamp: Date(),
duration: 0.5,
data: Data(repeating: 0xFF, count: 1024)
)
XCTAssertEqual(packet.data.count, 1024)
}
}