Skip to main content
Code samples

How to Use NCKit

Step-by-step guide for developers new to NCKit. No sample-app UI required โ€” copy the patterns below into your project.

Before you startโ€‹

  1. Install NCKit โ€” iOS: confirm Embed & Sign
  2. iOS: physical iPhone/iPad or Apple Silicon simulator (requirements)
  3. Imports compile in your target

Choose your use caseโ€‹

GoalNCKit APIDifficulty
Denoise an existing audio/video file (WAV, M4A, MP4, โ€ฆ)NCKitFileProcessorEasiest โ€” start here
Denoise live microphone in real timeNCKitStreamProcessorRecommended โ€” sample: Audio tab

Most apps only need file denoise (processFile). Live mic uses NCKitStreamProcessor with AVAudioEngine โ€” see Sample App.


How NCKit fits together (every integration)โ€‹

All paths use the same two setup calls, then one processing call:

1. let modelURL = try NCKitModelLocator.modelTarGzURL()
2. let processor = try NCKitProcessor(modelURL: modelURL)
3. Process audio โ†’ file: NCKitFileProcessor.processFile(...)
โ†’ live: NCKitStreamProcessor.process(buffer:) (recommended)

Create the processor once and reuse it. Creating a new NCKitProcessor per file costs ~50โ€“200 ms each time.


Step 1 โ€” Importโ€‹

import NCKit

Step 2 โ€” Copy-paste service (file denoise)โ€‹

Same pattern as the NCKit Sample AudioEngine / VideoProcessor โ€” one shared NCKitProcessor per session.

Add this to your project. Call denoiseFile from a background thread when the user picks a file.

import NCKit
import Foundation

enum DenoiseService {
/// Reuse one processor for the app session (create on first use).
private static var processor: NCKitProcessor?

private static func processorInstance() throws -> NCKitProcessor {
if let processor { return processor }
let modelURL = try NCKitModelLocator.modelTarGzURL()
let p = try NCKitProcessor(modelURL: modelURL, attenLimDb: 100, postFilterBeta: 0)
processor = p
return p
}

/// Denoise `inputURL` and return a new 48 kHz mono WAV URL.
static func denoiseFile(inputURL: URL) async throws -> URL {
let outputURL = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString + "_clean.wav")

return try await Task.detached(priority: .userInitiated) {
let proc = try processorInstance()
try NCKitFileProcessor.processFile(
inputURL: inputURL,
outputURL: outputURL,
processor: proc
)
return outputURL
}.value
}
}

Step 3 โ€” Call itโ€‹

// Example: user picked a file (after security-scoped access if needed)
Task {
do {
let cleanURL = try await DenoiseService.denoiseFile(inputURL: pickedFileURL)
// Play, upload, or save cleanURL (16-bit PCM WAV)
} catch let error as NCKitError {
print("NCKit error: \(error)")
} catch {
print("Other error: \(error)")
}
}

User-selected files (important)โ€‹

let accessed = inputURL.startAccessingSecurityScopedResource()
defer { if accessed { inputURL.stopAccessingSecurityScopedResource() } }
let cleanURL = try await DenoiseService.denoiseFile(inputURL: inputURL)

Without proper file access, you may get cannotOpenInput / CannotOpenInput even when the file looks valid.

What you get backโ€‹

  • Input: Any format AVAudioFile can read (WAV, M4A, MP3, MP4, โ€ฆ)
  • Output: 16-bit PCM WAV, 48 kHz, mono
  • Memory: streaming โ€” safe for long files

API details: NCKitFileProcessor


Path B โ€” Real-time microphone (advanced)โ€‹

Use this when you already have (or can build) a live audio capture pipeline.

Extra requirementsโ€‹

- NSMicrophoneUsageDescription in Info.plist
- Mic permission before starting AVAudioEngine
- NCKitStreamProcessor on the audio tap thread (not thread-safe)

Minimal flowโ€‹

import NCKit
import AVFoundation

// 1. Setup processor + stream adapter
let modelURL = try NCKitModelLocator.modelTarGzURL()
let processor = try NCKitProcessor(modelURL: modelURL)
let stream = NCKitStreamProcessor(processor: processor)

// 2. Configure audio session
let session = AVAudioSession.sharedInstance()
try session.setCategory(.playAndRecord, mode: .measurement, options: [.defaultToSpeaker])
try session.setPreferredSampleRate(48_000)
try session.setActive(true)

// 3. Install microphone tap
inputNode.installTap(onBus: 0, bufferSize: 4096, format: tapFormat) { buffer, _ in
try stream.prepare(inputFormat: buffer.format)
let frames = try stream.process(buffer: buffer)
for frame in frames {
// 480 Float samples @ 48 kHz mono โ€” denoised
}
}

Dry + denoised (A/B)โ€‹

try stream.prepare(inputFormat: buffer.format)
let dry = try stream.convertToTargetFormat(buffer)
let denoised = try stream.processConverted(dry)

End of sessionโ€‹

let tail = try stream.flush()
stream.reset() // requires NCKit 1.1.1+

Reference: NCKit_Demo/AudioEngine.swift. API: NCKitStreamProcessor.

Dry + denoised (A/B)โ€‹

NCKit does not set up AudioRecord / AudioTrack for you โ€” see Nckit_Android_Sample_App AudioEngine.kt. API details: NCKitStreamProcessor.

Direct file denoise without custom audio codeโ€‹

API details: NCKitProcessor


Handle errorsโ€‹

} catch NCKitError.missingModel {
// Framework not embedded correctly โ€” check Embed & Sign
} catch NCKitError.libraryInit {
// Intel simulator or corrupt model โ€” use a real device
} catch NCKitError.cannotOpenInput {
// Bad URL or missing security-scoped access
} catch NCKitError.unsupportedFormat {
// Unsupported audio format
} catch NCKitError.resampleFailed {
// AVAudioConverter failure
} catch {
print("Unexpected: \(error)")
}

Full list: NCKitError ยท Fixes: Common Errors


Common mistakes (new integrators)โ€‹

MistakeFix
Framework not Embed & SignTarget โ†’ General โ†’ Frameworks
NCKitStreamProcessor from multiple threadsUse audio tap thread only
New NCKitProcessor per fileReuse one instance (see DenoiseService above)
Intel Mac simulatorUpgrade to 1.2.1+ or use Rosetta / device
User-picked file won't openEnable security-scoped resource access
reset() missingUpgrade to 1.2.1 (or 1.1.1+) and reset package caches
Denoise blocks UIUse Task.detached for processFile
Expecting NCKit to build UINCKit is audio processing only โ€” UI is your app


Optional: loudness normalizationโ€‹

See NCKitAudioNormalizer.


API reference (lookup)โ€‹

TypePage
NCKitModelLocatorModel path
NCKitProcessorProcessor
NCKitStreamProcessorLive audio
NCKitFileProcessorFile denoise
NCKitAudioNormalizerNormalization
NCKitErrorErrors