Skip to content

nipponjo/open-dspc-flutter

Repository files navigation

open_dspc

pub.dev/open_dspc

open_dspc is a Dart/Flutter package for digital signal processing (DSP) built on top of a lightweight C library accessed through dart:ffi.

The package provides efficient implementations of common DSP algorithms while offering a convenient Dart API suitable for Flutter apps, scientific tooling, and real-time audio processing.

Features

  • Fourier transformsfft, ifft, rfft, irfft
  • Filtering & convolution — FIR/IIR filtering (lfilter), convolution (direct / FFT)
  • Spectral analysis — autocorrelation, linear and mel spectrograms
  • Signal analysis — LPC (Levinson–Durbin, Burg), peak detection
  • Signal processing utilities — resampling, framing
  • Mathematical tools — polynomial fitting and evaluation (polyfit, polyval)
  • Signal generation — sine/cosine signals, noise, sawtooth waves, pulses, sweeps

Usage

import 'package:open_dspc/open_dspc.dart';

open_dspc provides both:

  • FFTStatic, Conv.direct, Resample.process, ... for one-shot functional calls
  • RfftPlan, FftConvolver, Resampler, ... for reusable native contexts with lower overhead

For repeated processing of many equally sized blocks, the reusable plan/context APIs are typically faster because native setup and scratch buffers can be reused.

∿ Signals

final Float32List signal = SignalGenerator.sine(n: 1024, freqHz: 440.0, sampleRate: 16000.0);

FFT

final Complex32List xFft = FFTStatic.rfft(x);
final Float32List xFftMag = FFTStatic.rfftMag(x);

final rfftPlan = RfftPlan(n);
final Complex32List cpx = rfftPlan.execute(x);
final Float32List mag = rfftPlan.executeMag(x);

Notes:

  • FFTStatic is convenient for one-off transforms.
  • RfftPlan is preferable when the same n is used repeatedly.

∗ Convolution

final x = Float32List.fromList([1, 1, 1, 1, 1]);
final y = Float32List.fromList([1, 1, 1, 1, 1]);
final xyFull = Conv.direct(x, y, outMode: CorrOutMode.full, simd: true);
// [1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0]

Notes:

  • ConvMode.convolution and ConvMode.xcorr are both supported.
  • CorrOutMode.full, same, and valid follow SciPy-style output conventions.
  • simd: true enables the explicit SIMD path when supported by the target architecture.

↕ Resampling

final x = SignalGenerator.sine(n: 16000 * 8, freqHz: 440.0, sampleRate: 16000.0);
final y = Resample.process(x, origFreq: 16000, newFreq: 8000);

Notes:

  • Resample.process(...) is the simplest entry point for single blocks.
  • Resampler(...) is intended for repeated streaming or batch use with the same settings.

⚙ Example: reusable native plan

final plan = RfftPlan(1024);

final x1 = SignalGenerator.sine(n: 1024, freqHz: 440.0, sampleRate: 16000.0);
final x2 = SignalGenerator.sine(n: 1024, freqHz: 880.0, sampleRate: 16000.0);

final y1 = plan.executeMag(x1);
final y2 = plan.executeMag(x2);

plan.close();

This pattern is generally the best choice for benchmarking, real-time processing, or any workload where the same transform/configuration is reused many times.

FFT Benchmark Summary

open_dspc supports multiple native FFT backends: pffft, pocketfft-c, and kissfft (plus a Dart-only baseline via fftea).

Benchmarks were recorded on: AMD Ryzen 9 7900 (Windows PC), Apple M4 (MacBook), Exynos 9810 (Samsung Galaxy S9, measured inside a Flutter isolate).

Across tested devices, pffft is generally the fastest backend for sizes it supports, due to its SIMD-oriented implementation.
Its main limitation is supported transform lengths: nfft = 2^a * 3^b * 5^c with a >= 5.

Backend size support:

  • pffft: 2^a * 3^b * 5^c, a >= 5
  • pocketfft-c: all sizes
  • kissfft: even sizes only

Because pocketfft-c is typically the next fastest while supporting arbitrary sizes, the default native configuration uses a hybrid backend:

  • use pffft when the size is supported
  • otherwise fall back to pocketfft-c

The plots also show a clear benefit from plan reuse (RfftPlan.execute) over one-shot calls (FFTStatic.rfft), especially at smaller FFT sizes.
For full benchmark scripts and raw results, see bench/.

Benchmark curves Benchmark curves2

Architecture

open_dspc consists of two layers:

C core library

  • Portable DSP implementations written in C
  • Optional SIMD acceleration
  • FFT backends such as pffft, pocketfft, or kissfft

Dart bindings

  • Thin dart:ffi wrappers
  • Memory-safe Dart APIs
  • Support for both
    • functional APIs (single-shot operations)
    • transform classes (reusable contexts for performance)

License

open_dspc is licensed under the MIT License.

This repository also bundles third-party FFT implementations under their own licenses. Which of these are included in a given native build depends on the selected FFT backend. The default build uses pffft together with pocketfft-c in the hybrid backend.

Bundled third-party licenses:

About

⚡ Dart/Flutter DSP package with a lightweight native C backend

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors