Performance Troubleshooting
File Processing Is Slowโ
Expected performance: ~20ร faster than realtime on iPhone 14+. A 10-minute file should complete in ~28 seconds.
If significantly slower:
-
Processor reuse โ are you creating a new
NCKitProcessorper file? This adds 50โ200ms per file:// SLOW
for url in files {
let proc = try NCKitProcessor(modelURL: modelURL) // โ 100ms per file
try NCKitFileProcessor.processFile(..., processor: proc)
}
// FAST
let proc = try NCKitProcessor(modelURL: modelURL) // โ once
for url in files {
try NCKitFileProcessor.processFile(..., processor: proc)
} -
Unnecessary resampling โ if your recordings are already 48 kHz mono, ensure they're saved in that format to skip the
AVAudioConverterstep. -
Task priority โ use
.userInitiatedfor processing tasks:Task.detached(priority: .userInitiated) { ... }
High CPU During Real-Time Processingโ
Symptom: Device heats up, CPU usage >25% while NC is active.
Solutions:
-
Reduce attenuation โ lower
attenLimDbslightly reduces post-processing work:processor.setAttenLim(60) // was 100 -
Increase buffer size โ larger IO buffer means fewer interrupts per second:
try AVAudioSession.sharedInstance().setPreferredIOBufferDuration(0.02) // 20ms instead of 10msNote: This increases latency from 10ms to 20ms.
-
Monitor thermal state and reduce processing when throttled:
NotificationCenter.default.addObserver(
forName: ProcessInfo.thermalStateDidChangeNotification,
object: nil, queue: .main
) { _ in
let state = ProcessInfo.processInfo.thermalState
if state >= .serious {
processor.setAttenLim(40) // reduce aggressiveness
} else {
processor.setAttenLim(100) // restore
}
}
Audio Glitches / Dropoutsโ
Symptom: Clicks, pops, or dropouts in real-time processing.
Root cause: Almost always memory allocation in the audio render callback.
Checklist:
-
outputBufferpre-allocated beforeinstallTap - No
[Float](repeating:count:)inside the tap closure - No
print()statements inside the tap closure - No
DispatchQueue.main.asyncinside the tap closure - No Swift actor access inside the tap closure
Profile with Instruments:
- Time Profiler โ look for allocation activity on the audio thread
- Allocations โ filter by "Audio I/O Thread" โ should show zero allocations per frame
High Memory During File Processingโ
Symptom: Memory grows steadily during long file processing.
Cause: You may be accumulating processed samples in a [Float] array in memory.
NCKit's NCKitFileProcessor itself uses constant memory โ but if you load the output WAV back into memory with Data(contentsOf: url) or a custom WAV loader on a large file, that loads the entire file at once.
Solution: Process in chunks or stream the output directly to its destination (Files.app, network, etc.) without loading it into memory.