Pre-release docs for SmartSpectra SDK 3.2.0-rc.6. This RC channel may describe APIs or install commands that differ from the latest stable release.

SmartSpectra SDK
C++C++ on Windows

.NET on Windows

SmartSpectra.Net — C# / .NET 8 wrapper for the SmartSpectra SDK on Windows.

SmartSpectra.Net is a managed C# wrapper over the SmartSpectra C ABI shim. It exposes IDisposable sessions, .NET events, and protobuf metrics types — no P/Invoke boilerplate required in application code.

Prerequisites

Add the package source (one-time)

# Stable feed
nuget sources add -Name SmartSpectra `
    -Source https://packages.presagetech.com/nuget/index.json

# RC feed (for pre-release builds)
nuget sources add -Name SmartSpectra-RC `
    -Source https://packages.presagetech.com/nuget-rc/index.json

Install the package

Add to your .csproj:

<!-- Stable release -->
<PackageReference Include="SmartSpectra.Net" Version="<version>" />

<!-- RC build (requires SmartSpectra-RC source) -->
<PackageReference Include="SmartSpectra.Net" Version="<version>-rc.<n>" />

Google.Protobuf, SmartSpectra.Net.Protos, and the native runtime DLLs (smartspectra.dll, smartspectra_capi.dll, opencv_world*.dll) are copied to your output directory automatically by the package targets.

Quick start: video file

using Presage.SmartSpectra;

var config = new SmartSpectraConfig
{
    ApiKey = Environment.GetEnvironmentVariable("SMARTSPECTRA_API_KEY")
        ?? throw new InvalidOperationException("SMARTSPECTRA_API_KEY is required"),
    RequestedMetrics = Array.Empty<int>(),
};

using var session = SmartSpectraSession.Create(config);

session.ValidationChanged += (_, hint, timestampUs) =>
    Console.WriteLine($"Validation: {hint} @ {timestampUs}");

session.MetricsReceived += (metrics, timestampUs) =>
{
    var br = metrics.Breathing?.Rate.FirstOrDefault()?.Value;
    if (br.HasValue)
        Console.WriteLine($"Breathing rate: {br:F1} bpm @ {timestampUs / 1_000_000.0:F1}s");
};

session.ErrorOccurred += error =>
    Console.Error.WriteLine($"Error: {error}");

var error = session.RunFile("sample.mp4", timestampsPath: null);
if (!error.Ok)
    throw new SmartSpectraException(error);

Quick start: custom frames

Use custom input when your app owns camera capture:

using var session = SmartSpectraSession.Create(config);

var startError = session.StartCustom(FrameTransform.None);
if (!startError.Ok)
    throw new SmartSpectraException(startError);

var frameError = session.SendFrame(
    frameBytes,
    width,
    height,
    strideBytes,
    PixelFormat.Nv12,
    timestampUs);
if (!frameError.Ok)
    Console.Error.WriteLine(frameError);

session.Stop();
session.Wait(timeoutMs: 5000);

API reference

SmartSpectraConfig

PropertyTypeDescription
ApiKeystringAPI key authentication
RequestedMetricsint[]Native MetricType integer values. Empty uses the SDK default breathing metric set

SmartSpectraSession

Create sessions with SmartSpectraSession.Create(config).

Events — all fire on internal worker threads; marshal to the UI thread if needed.

EventPayloadDescription
StatusChangedProcessingStatusGraph lifecycle state
ValidationChanged(ValidationCode code, string hint, long timestampUs)Face / imaging readiness
MetricsReceived(Metrics metrics, long timestampUs)Serialized protobuf metrics decoded into managed types
ErrorOccurredSmartSpectraErrorRuntime error
FrameDisposed(bool sent, long timestampUs)Custom-input frame acceptance result

Lifecycle methods:

SmartSpectraSession Create(SmartSpectraConfig config);
SmartSpectraError RunFile(string videoPath, string? timestampsPath = null);
SmartSpectraError StartCustom(FrameTransform transform = FrameTransform.None);
SmartSpectraError SendFrame(ReadOnlySpan<byte> data, int width, int height,
    int strideBytes, PixelFormat pixelFormat, long timestampUs);
void Stop();
bool Wait(int timeoutMs = -1);

Error handling

Lifecycle methods (RunFile, StartCustom, SendFrame) return a SmartSpectraError describing the outcome:

PropertyTypeDescription
CodeSmartSpectraErrorCodeError category — Ok (0) means success
MessagestringHuman-readable detail
Retryablebooltrue if the caller can safely retry the operation
OkboolShorthand for Code == SmartSpectraErrorCode.Ok

Create throws SmartSpectraException on failure (wrapping a SmartSpectraError exposed via the Error property) instead of returning it. Wait throws on an unexpected native status; a timeout simply returns false.

Metrics

MetricsReceived uses Presage.SmartSpectra.Metrics from SmartSpectra.Net.Protos, with the same protobuf fields as the native SDK: Breathing, Cardio, Face, and Eda.

Thread safety

All events fire on internal worker threads. For UI updates, dispatch to the UI thread:

// WPF
session.MetricsReceived += (metrics, _) =>
    Dispatcher.InvokeAsync(() => UpdateUI(metrics));

// WinUI 3
session.MetricsReceived += (metrics, _) =>
    DispatcherQueue.TryEnqueue(() => UpdateUI(metrics));

Package layout

SmartSpectra.Net.<version>.nupkg
├── lib/net8.0/
│   ├── SmartSpectra.Net.dll
│   ├── SmartSpectra.Net.Native.dll
│   └── SmartSpectra.Net.Protos.dll
├── runtimes/win-x64/native/
│   ├── smartspectra.dll
│   ├── smartspectra_capi.dll
│   └── opencv_world4100.dll
└── build/
    └── SmartSpectra.Net.targets

Supported platforms

PlatformStatusNotes
Windows 10 / 11 (x64)Experimental.NET 8 runtime required

Troubleshooting

ProblemFix
BadImageFormatExceptionEnsure the project targets x64, not AnyCPU — the native DLLs are x64-only
DllNotFoundExceptionCheck that the native runtime DLLs are in the output directory
FileNotFoundException: SmartSpectra.Net.ProtosThe protos DLL must be in the same directory as SmartSpectra.Net.dll
No metrics callbacksCheck the returned SmartSpectraError from RunFile, StartCustom, or SendFrame
Events fire on the wrong threadUse Dispatcher.InvokeAsync / DispatcherQueue.TryEnqueue to marshal to the UI thread

On this page