Bindings

Swift

Swift binding for the Rapidly SDK, for iOS and macOS apps via Swift Package Manager.

The Swift binding wraps the Rapidly SDK's native C engine in an idiomatic Swift class, distributed as a Swift Package alongside a signed Apple xcframework. The same engine runs natively on iOS, iPadOS, and macOS. See Overview for what's inside the engine and the supported Apple targets.

Install

Requirements: iOS 14 or later, macOS 11 or later, Xcode 15 or later, Swift 5.9 or later.

In Xcode, open File → Add Package Dependencies and paste:

https://github.com/rapidly-labs/rapidly-sdk

Pick the latest version, then add the RapidlySDK library to your target.

For Package.swift-based projects:

.package(url: "https://github.com/rapidly-labs/rapidly-sdk", from: "1.0.0")

Or with the Swift 6 CLI:

swift package add-dependency https://github.com/rapidly-labs/rapidly-sdk --from 1.0.0

Alternative: drag-and-drop xcframework

To vendor the binary directly instead of using SwiftPM, download RapidlyEngine.xcframework.zip from the GitHub Release, drag the framework into your Xcode project, and import the raw C API:

import RapidlyEngineC

This gives you the same C surface documented on the C / C++ page. The Swift-native class described below is only available via SwiftPM.

Basic usage

Import the Swift-native binding:

import RapidlyEngine

Create an engine by specifying a model file path, channel count, and sample rate:

let engine = RapidlyEngine(
    modelFilepath: "models/speech-denoise-32ms.v1.0.rapidly",
    numOfChannels: 2,
    sampleRate: 44100
)

guard let engine else {
    fatalError("Unable to create the Rapidly engine.")
}

The initializer is failable. It returns nil only when the model file is missing or unreadable. License coverage never causes a nil result.

Add audio for processing. The API supports both interleaved and separate channel formats:

// Interleaved format (L1, R1, L2, R2, ...)
engine.addAudioInterleaved(pcmChannels: inputBuffer, numOfSamples: numOfSamples)

Retrieve processed audio. Processing introduces latency, so query the number of available samples first:

let pending = engine.getNumOfPendingSamples()
engine.getAudioInterleaved(pcmChannels: outputBuffer, numOfSamples: pending)

When finished, call close() to release the underlying processor:

engine.close()

To capture the processing tail caused by model latency, add silent audio (zeros) after your input stream ends.

Threading

Drive each engine from a single thread. Under Swift 6 strict concurrency, RapidlyEngine is intentionally not declared Sendable. For batch patterns where each task or actor owns its own engine, no Sendable work is needed. To share a single engine across actors, wrap it in your own @unchecked Sendable adapter and serialise access inside the wrapper.

See One vs multiple engines for the universal threading rules and the stop-then-close sequence.

Licensing

Call RapidlyEngine.addLicense before constructing any engine. See Pricing for licensing options.

guard RapidlyEngine.addLicense("lk_...") else {
    fatalError("Rapidly license could not be verified.")
}

Apple platform specifics

The xcframework is code-signed; the macOS slice is also notarized.

Each Apple slice bundles a PrivacyInfo.xcprivacy manifest declaring the privacy-impacting APIs the engine uses (file timestamp access for model loading). No further App Store privacy disclosures are required for the engine itself.

Types

RapidlyEngine

public class RapidlyEngine

The Swift-native audio engine.

RapidlyEngine.ProcessorInfo

public struct ProcessorInfo {
    public var sampleRate: Double           // Sample rate the model was trained on
    public var numOfModelChannels: Int      // Number of channels used internally
    public var latencyInSamples: Int        // Maximum processing latency
}

The processor automatically converts sample rates and channel formats to match the model.

RapidlyEngine.Parameters

public enum Parameters: UInt32 {
    case maximumAttenuation     = 0x0001
    case sensitivity            = 0x0002
    case maskExtrapolation      = 0x0003
    case firstModelSensitivity  = 0x1000
}

For stem-separation models with multiple internal models, address an individual stem by offsetting firstModelSensitivity with the model index:

engine.setParameter(for: .firstModelSensitivity, to: 50.0)                          // first model
engine.setParameter(for: Parameters(rawValue: 0x1000 + 1)!, to: 25.0)               // second model

Methods

Licensing

addLicense

public static func addLicense(_ licenseString: String) -> Bool

Adds a license key to remove audio watermarking from the output.

ParameterDescription
licenseStringLicense string issued by Rapidly.

Returns: true if the license is valid, false otherwise.

Engine lifecycle

init(modelFilepath:numOfChannels:sampleRate:)

public init?(
    modelFilepath: String,
    numOfChannels: UInt32,
    sampleRate: Double
)

Creates an engine and loads a single model file.

ParameterDescription
modelFilepathPath to the .rapidly model file on disk.
numOfChannelsNumber of audio channels to process.
sampleRateSample rate of the input audio.

Returns: A valid instance on success, nil when the model file is missing or unreadable.

init(modelFilepaths:numOfChannels:sampleRate:)

public init?(
    modelFilepaths: [String],
    numOfChannels: UInt32,
    sampleRate: Double
)

Creates a processor that performs stem separation, loading a set of model files. The number of stems is derived from modelFilepaths.count.

close

public func close()

Releases the underlying processor and frees its resources. Safe to call multiple times. After close, all audio methods become no-ops and read methods return false or zero.

resetProcessorState

public func resetProcessorState()

Resets the processor state and clears all internal delay lines. Call this when starting a new audio stream.

Audio I/O

addAudio

public func addAudio(
    pcmChannels: [UnsafeMutableRawPointer?],
    numOfSamples: UInt32
)

Adds audio from separate per-channel buffers.

addAudioInterleaved

public func addAudioInterleaved(
    pcmChannels: UnsafeMutableRawPointer?,
    numOfSamples: UInt32
)

Adds audio from an interleaved buffer (L1, R1, L2, R2, ...).

getNumOfPendingSamples

public func getNumOfPendingSamples() -> UInt32

Returns the number of processed samples available for retrieval.

getAudio

@discardableResult
public func getAudio(
    pcmChannels: [UnsafeMutableRawPointer?],
    numOfSamples: UInt32
) -> Bool

Retrieves processed audio into separate per-channel buffers.

getAudioInterleaved

@discardableResult
public func getAudioInterleaved(
    pcmChannels: UnsafeMutableRawPointer?,
    numOfSamples: UInt32
) -> Bool

Retrieves processed audio into an interleaved buffer.

Parameters

getParameterValue

public func getParameterValue(for param: Parameters) -> Float

Returns the current value of a parameter.

setParameter

public func setParameter(for param: Parameters, to value: Float)

Sets a parameter value.

Processor info

getProcessorInfo

public func getProcessorInfo() -> ProcessorInfo

Returns a ProcessorInfo struct describing the processor.

Output busses

The Swift wrapper exposes engine-wide and per-stem-model controls through Parameters. For introspection of named output busses (for example, the clean speech and noise busses of a denoise model) and per-bus gain control, drop down to the raw C API by importing RapidlyEngineC. The C functions documented on the C / C++ page are all callable directly from Swift.