Flutter Bindings¶
Dart FFI bindings to cactus_engine.h.
Integration¶
- Copy
android/libcactus_engine.soto your app'sjniLibs/arm64-v8a/ - Add
apple/cactus-ios.xcframeworkto your Xcode project (iOS) - Add
apple/cactus-macos.xcframeworkto your Xcode project (macOS) - Copy
cactus.dartinto your Dart source tree - Add
ffitopubspec.yaml
Usage¶
import 'dart:ffi';
import 'cactus.dart';
import 'package:ffi/ffi.dart';
final modelPath = '/path/to/model'.toNativeUtf8();
final model = cactusInit(modelPath, nullptr, false);
calloc.free(modelPath);
const messagesJson = '[{"role":"user","content":"Hello"}]';
final msgs = messagesJson.toNativeUtf8();
final buf = calloc<Int8>(65536);
cactusComplete(model, msgs, buf.cast(), 65536, nullptr, nullptr, nullptr, nullptr, nullptr, 0);
final response = buf.cast<Utf8>().toDartString();
calloc.free(msgs);
calloc.free(buf);
cactusDestroy(model);
Streaming transcription¶
Push 16 kHz mono PCM16 as it arrives; each call returns {"success":true,"confirmed":...,"pending":...} (confirmed is final, pending is the volatile tail).
final opts = '{"language":"en"}'.toNativeUtf8();
final stream = cactusStreamTranscribeStart(model, opts);
final out = calloc<Int8>(65536);
for (final chunk in pcmChunks) { // each: 16 kHz mono PCM16 bytes
final p = calloc<Uint8>(chunk.length)..asTypedList(chunk.length).setAll(0, chunk);
cactusStreamTranscribeProcess(stream, p, chunk.length, out.cast(), 65536);
calloc.free(p);
// parse {"confirmed":...,"pending":...} from out.cast<Utf8>().toDartString()
}
cactusStreamTranscribeStop(stream, out.cast(), 65536);
calloc.free(opts);
calloc.free(out);