A lightweight, high-performance wake word detection library for Android. It runs entirely on-device using openWakeWord-compatible ONNX models — no cloud dependency and minimal battery impact.
- Dual-stage VAD (Speex + Silero) — Always-on Speex front-end (native, tiny CPU cost) plus Silero VAD (ONNX) for accurate confirmation; Silero is invoked only when needed to save power.
- Hardware audio preprocessing — Uses
AutomaticGainControlandNoiseSuppressorwhen available to improve robustness in noisy conditions. - Batched ONNX inference — Mel spectrogram, embeddings and classification are batched and run via ONNX Runtime with optional NNAPI/XNNPACK/QNN acceleration.
- Optional verifier model — Add a secondary ONNX verifier to further reduce false positives.
- Zero-allocation pipeline — Pre-allocated direct buffers and ring buffers minimize GC pauses and keep latency low.
- Coroutine-friendly API —
suspend-based detection fits cleanly with Kotlin coroutines. - Small runtime footprint — Only ONNX Runtime and Kotlin Coroutines as dependencies.
Add the JitPack repository to your project-level settings.gradle.kts:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}Then add the dependency to your module-level build.gradle.kts:
dependencies {
implementation("com.github.suxsem:AndroidWakeWord:v0.0.1")
}Replace version with the desired release tag or commit hash (e.g. v1.0.0).
-
Add the
RECORD_AUDIOpermission to yourAndroidManifest.xml(if not already present) and request it at runtime before starting detection:<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Place your ONNX models in your app's
assets/folder:your_wakeword.onnx— required classifier model (OpenWakeWord-compatible) 📦verifier.onnx— optional verifier model to reduce false positives ✅
Files in this repo you might check:
val detector = WakeWordDetector(
context = applicationContext,
modelFile = "my_wake_word.onnx", // classifier model in assets/
verifierFile = "verifier.onnx", // verifier model in assets/ (or null)
minScore = 0.7f, // minimum classifier score to trigger
minVerifierScore = 0.1f, // minimum verifier score (0 to skip verification)
onDetected = { score ->
Log.d("WakeWord", "Detected! score=$score")
}
)
// Start detection inside a coroutine scope
scope.launch {
detector.startDetection()
}You can pause and later resume detection without releasing resources:
// Pause (stops the microphone)
detector.pauseDetection()
// Resume
scope.launch {
detector.startDetection()
}When you are done, pause detection and release all resources:
detector.pauseDetection()
detector.releaseResources()Note: After
releaseResources()the detector instance cannot be reused — create a new one if needed.⚠️
The classifier is an openWakeWord-compatible ONNX model. You can obtain one from:
| Source | Description |
|---|---|
| openwakeword.com | Free pre-trained models and paid custom model training |
| hawake-wakeword | Custom OpenWakeWord training pipeline for generating wake word models |
| home-assistant-wakewords-collection | Community Collection of Wake-Words for Home Assistant based on OpenWakeWord |
| openWakeWord | The original OpenWakeWord project with some pre-trained models and general instructions on how to train a custom model |
The verifier is an optional secondary model that further validates detections, reducing false positives. You can train your own using the Jupyter notebook included in this repository:
TrainOpenWakeWordVerifierModel.ipynb
- Android API 24+ (Android 7.0)
RECORD_AUDIOpermission granted at runtime