add microphone capture and stable code signing for TCC persistence

Adds --capture-mic/--mic-output for a second, independently-captured audio
track (mic vs system, written to separate outputs to avoid interleaving
corruption). Embeds Info.plist at link time so the binary carries a stable
CFBundleIdentifier and the usage-description keys TCC requires, and adds
scripts/build-signed.sh + scripts/create-signing-identity.sh so a rebuilt
binary keeps the same signing identity instead of losing granted
permissions on every rebuild.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sttlab-tech
2026-08-09 13:10:08 +02:00
parent 56ac954369
commit 678557caf7
10 changed files with 678 additions and 9 deletions
@@ -0,0 +1,29 @@
import AudioToolbox
import CoreAudio
import Foundation
/// Resolves hardware audio input devices, e.g. the built-in or currently
/// selected microphone. Unlike system audio capture, this talks to a real
/// input device directly and needs no process tap or aggregate device.
public class InputDeviceResolver {
/// Returns the system's current default audio input device.
public static func defaultInputDevice() throws -> AudioObjectID {
var address = getPropertyAddress(selector: kAudioHardwarePropertyDefaultInputDevice)
var deviceID = AudioObjectID(kAudioObjectUnknown)
var size = UInt32(MemoryLayout<AudioObjectID>.size)
let status = AudioObjectGetPropertyData(
AudioObjectID(kAudioObjectSystemObject), &address, 0, nil, &size, &deviceID)
guard status == kAudioHardwareNoError, deviceID != kAudioObjectUnknown else {
AudioTeeLogging.logger.error(
"Failed to resolve default input device", context: ["status": String(status)])
throw AudioTeeError.defaultInputDeviceUnavailable(status)
}
AudioTeeLogging.logger.debug(
"Resolved default input device", context: ["device_id": String(deviceID)])
return deviceID
}
}