{"slug": "satori-offline-android-voice-notes-with-on-device-stt-and-local-llms", "title": "Satori – Offline Android voice notes with on-device STT and local LLMs", "summary": "An independent developer released Satori, an open-source Android voice-notes app that runs every stage of its pipeline 100% offline on the phone, using NVIDIA Parakeet v3/v2, Cohere Transcribe and AI4Bharat IndicConformer speech models via sherpa-onnx and ONNX Runtime 1.28.2, plus Gemma 3 1B, Gemma 4 E2B and Qwen 3.5 0.8B for note synthesis on custom-patched llama.cpp ARM64 kernels. Satori performs live transcription, first-person note synthesis, to-do extraction and mind-map linking with zero accounts, zero cloud servers and zero telemetry, touching the network only to download model weights from Hugging Face, and adds English↔German live translation and a Malayalam→English reading pass via AI4Bharat IndicTrans2 200M. The app supports the Motorola razr 70 plus cover screen (1080×1272, 480×410 dp), including power-key double-press capture over the lock screen with layout clearance around the 232 px camera band.", "body_md": "### Fully offline voice recorder, live transcriber, journal & meeting synthesizer, and personal mind map for Android — powered 100% by on-device AI.\n\nI wanted a way to capture thoughts on the go with a quick double-press of a physical hardware key—without unlocking my phone or getting pulled into a screen—and have those notes accumulate over time into a living mind map.\n\nI use Satori every day for **journaling**, **quick thoughts**, **ideas**, **self-development**, **local AI and engineering notes**, and **transcribing meetings**. I didn't have the time to audition a dozen different note-taking apps, and I refused to pay recurring subscriptions just to hand my private voice recordings and personal reflections over to someone else's cloud servers. Instead, I built this.\n\nEvery stage of Satori runs **100% offline on the phone**:\n\n- **Live speech recognition** while you walk or sit in a meeting (`NVIDIA Parakeet v3/v2` ,`Cohere Transcribe` ,`AI4Bharat IndicConformer` , and`Silero VAD` via`sherpa-onnx` and ONNX Runtime`1.28.2` ).\n- **First-person note synthesis, session naming, to-do extraction, and mind-map linking** via local instruction-tuned language models (`Gemma 3 1B` ,`Gemma 4 E2B` ,`Qwen 3.5 0.8B` ) running on custom-patched`llama.cpp` ARM64 kernels.\n- **Neural reading & translation bridges** for live**English ↔ German** conversation translation and an internal**Malayalam → English** reading pass (`AI4Bharat IndicTrans2 200M` ) so Malayalam voice notes receive the same structured English notes, reminders, and mind-map connections.\n- **Zero accounts, zero cloud servers, zero telemetry.** The network is touched only when downloading model weights directly from Hugging Face.\n\nI am sharing Satori as open source hoping it will be useful to anyone who wants to clone, customize, and build a private voice companion for themselves or for the people they love.\n\nBuilt around the **Grille** typographic design system (`Space Grotesk` + `Doto` dot-matrix tabular counters + `#D71921` recording red on `#000000` OLED black), Satori is engineered for both standard Android displays (`1080×2640`) and the **Motorola razr 70 plus** external cover screen (` 1080×1272`, `480×410 dp`), including hardware power-key double-press capture over the lock screen and automatic layout clearance around the `232 px` physical camera band.\n\nDouble-pressing the physical power key wakes the folded phone straight into recording (`QuickKeyActivity`), keeping all interactive controls clear of the `232 px` hardware camera and flash band in both standard (`ROTATION_0`) and tent/flipped (` ROTATION_180`) postures.\n\n| Cover View | Use Case & What It Shows | \n|---|---|\n| **Quick Power-Key Capture** (`cover-recording.png` ) | Capturing an evening walk reflection without unfolding the phone: `Doto` dot-matrix timer,`Voice note` category selector,`EN` language key, streaming`Parakeet v3` transcript, and the tactile**Grille**`Stop` button positioned above the camera band. | \n| **Cover Home** (`cover-home.png` ) | Browsing recent **Journal** ,**Voice note** , and**Meeting** sessions on the folded display with tabular`Doto` durations, search/mind-map/settings actions, and one-tap**Grille** recording. | \n| **Live Translation** (`cover-translate.png` ) | Real-time **German → English** translation (`Record as → Translate` ), pairing the spoken German transcript with live English translations on the cover display. | \n| **Cover Mind Map** (`cover-mindmap.png` ) | Interactive radial knowledge graph centered on `You` (`10` recordings across`Journaling` ,`Local LLMs & AI` ,`Self-dev` ,`Quick Ideas` ,`Meetings` ,`Deep Work` , and`Habits` ), adapted for the square cover viewport. | \n\nEach recording belongs to a category—**Voice note**, **Meeting**, **Idea**, **To-do**, or custom categories like **Journal**—that governs how the on-device LLM structures your notes and whether spoken action items become scheduled reminders or ideas.\n\n| Inner View | Use Case & What It Shows | \n|---|---|\n| **Home** (`inner-home.png` ) | Open **To do** list (`Block 2 hours for deep work before 10 AM` ),`1 suggested` inbox link,`1 idea` link, chronological**Recordings** across`Journal` ,`Idea` ,`Meeting` , and`Voice note` , and the docked**Grille** record bar. | \n| **Active Recording** (`inner-recording.png` ) | Real-time streaming transcription ( `Parakeet v3` ) with live partial utterance tracking and instant`Record as` / language switching. | \n| **`Record as` Sheet** (`inner-record-as.png` ) | Switching category ( `Voice note` ,`Meeting` ,`Idea` ,`To-do` ,`Translate` ) or spoken language (`English or German` ,`Malayalam` ) before or during a recording. | \n| **Categories Manager** (`inner-categories.png` ) | Built-in categories plus custom user categories ( `Journal — Daily reflections, habits and self-dev notes` ), each mapped to a note-synthesis style (`Short notes and to-dos` ,`Decisions, facts and to-dos` , or`Sections for a long meeting` ). | \n| **Journaling & Self-Dev** (`inner-journal.png` ) | First-person journal synthesis ( `Evening journal: deep work and focus` ) distilled from an evening walk reflection, with expandable transcript provenance (`Show what was said` ). | \n| **Technical & LLM Notes** (`inner-details.png` ) | Structured engineering notes ( `On-device LLM latency and KV cache` ) capturing concrete numbers and trade-offs in first-person voice without generic AI filler. | \n| **Meeting Transcript & Player** (`inner-transcript.png` ) | Timestamped meeting transcript ( `Architecture sync: local LLM latency` ) with the built-in audio player (`Play from here` on any line) and file size readout. | \n| **To-Dos & Suggested Inbox** (`inner-todos-suggested.png` ) | Calendar-grounded open **To do** reminders alongside the**Suggested to-dos** review sheet (`Keep` ,`Dismiss` ,`Move to ideas` ,`Keep all` ) for tasks inferred from meetings and journal reflections. | \n\nOver days and weeks, Satori connects your recordings into a two-level knowledge graph (**Themes** and per-recording **Topics**) and gathers spoken wishes into a dedicated **Ideas** collection.\n\n| Inner View | Use Case & What It Shows | \n|---|---|\n| **Mind Map Overview** (`inner-mindmap.png` ) | Ego-centric knowledge graph centered on `You` (`Core` ,`Recent` ,`All` filters, theme search, and recording counts across`Journaling` ,`Local LLMs & AI` ,`Self-dev` ,`Quick Ideas` ,`Meetings` ,`Deep Work` ,`Streaming STT` , and`Habits` ). | \n| **Theme Node Drill-Down** (`inner-mindmap-node.png` ) | Inside the `Journaling` theme node (`4 recordings · Pinned in Core` ): radial sub-graph of child topics (`Deep work` ,`Morning walk` ,`Evening review` ,`Attention` ,`Sleep & energy` ,`Weekly reset` ,`Reading habit` ,`Stoic notes` ), AI-written**Summary across recordings** , and linked**Topics in this theme** . | \n| **Ideas Collection** (`inner-ideas.png` ) | Every spoken wish or idea extracted across your `Journal` and`Meeting` recordings, grouped by source session and convertible into a scheduled to-do in one tap. | \n| **On-Device Model Manager** (`inner-models.png` ) | Local model manager ( `Parakeet v3` ,`Parakeet v2` ,`Cohere Transcribe` ,`Malayalam (AI4Bharat)` ,*Better transcript after Stop* , and custom recognition vocabulary). | \n\n- **100% Offline & Private** : Every byte of audio, every transcript segment, every synthesized note, and your entire mind map live in a local Room SQLite database (`AppDatabase` v13) on your phone. Nothing is ever uploaded to a server.\n- **\"The Recorder Wins\" Preemption** : Starting a recording—from the Home screen, the cover screen, or a double-press of the physical power key over the lock screen—opens the microphone immediately and preempts any running background AI task within milliseconds.\n- **First-Person Notes, Zero AI Slop** : Generic meeting bots write third-person filler (*\"The speaker discusses...\"* ). Satori's prompts and GBNF grammar schemas force the local LLM to write direct, first-person notes (*\"Pre-faulting GGUF weights at 120 MB/s prevents audio underruns\"* ), verified by`PromptEcho` filters.\n- **Calendar-Accurate To-Dos without LLM Math** : Small language models hallucinate calendar arithmetic. Satori spots relative dates and times deterministically (`TodoTimeResolver` for English/German and`MalayalamTodoCues` for Malayalam) relative to the recording's start timestamp, passing verified`T1` /`T2` tokens to the model and grounding every extracted item against the cited segment (`TodoGrounding` ).\n- **Engineered for Real Phone Memory Limits** : Multi-gigabyte GGUF models are pre-faulted at a paced`120 MB/s` (`0 MB/s` during active recording) with`MAP_POPULATE` disabled,`/proc/meminfo` (`MemAvailable` ) safety floors, and immediate page-cache reclamation (`madvise(MADV_PAGEOUT)` ) on unload.\n\n- **Zero-wait microphone capture** :`RecordingService` opens`AudioRecord` (16 kHz mono PCM) the instant you tap**Record** , buffering audio while the speech recognizer loads in the background so the first words you speak are never lost.\n- **Categories & `Record as`** :\n  - Ships with four starter categories—**Voice note** ,**Meeting** ,**Idea** , and**To-do** —plus custom user-defined categories (`Settings → Categories` , such as**Journal** ). Each category maps to a recording style (`SIMPLE_LISTENING` ,`SHORT_MEETING` , or`LONG_MEETING` ) that governs how its notes and action items are structured.\n  - Switch categories before recording, mid-recording via the top `Record as` chip, or retroactively on any finished recording via**Change type** (which rewrites the notes in the new category's style while preserving your title and to-dos).\n- Ships with four starter categories—\n- **Spoken languages & mid-recording switching** :\n  - **English and German** out of the box via`NVIDIA Parakeet TDT 0.6B v3` (`~670 MB` ).\n  - **Malayalam** (`മലയാളം` ) via`AI4Bharat IndicConformer 120M INT8` (`~140 MB` ). When*Language in Record as* is enabled, you can switch between`English or German` and`Malayalam` mid-recording between two sentences.\n- **Custom vocabulary (`Words to recognize`)** : Add names, acronyms, and domain terms (one per line) in*Advanced settings* to boost their recognition in`Parakeet v3` during live capture and*Transcribe again* .\n- **Double-press power key (`QuickKeyActivity`)** : Binds to Motorola's hardware double-tap power gesture (`com.motorola.mykey` ), debouncing accidental bounce presses within`1,000 ms` (`QuickKeyRepeatFilter` ) and waking over the lock screen (`Hold to stop` ,`Hold to change` for pocket safety).\n\n- Selecting **Translate** in`Record as` (`REAL_TIME_TRANSLATION` ) transcribes spoken English or German and translates finished sentences into the target language configured under`Settings → Translate into` (`English` or`German` ).\n- Automatically detects the spoken language (`German into English` , or`Already English: nothing to translate` when input and target match).\n- Displays a dedicated **Translation** tab, running either live every few sentences (`As you speak` ) or in one batch after stopping (`After recording` ).\n\nWhen you press **Stop**, the microphone closes and `RecordingFinisher` processes finished recordings sequentially in `LlmProcessingService` while leaving the recorder free for your next thought:\n\n``` php\nflowchart LR\n    Stop[\"Stop Recording\"] --> Lines[\"1. Lines\\n(Flush streaming STT)\"]\n    Lines --> Redo{\"2. Better transcript\\nafter Stop?\"}\n    Redo -- \"Parakeet v2 / Cohere /\\nIndicConformer\" --> Retranscribe[\"Re-transcribe WAV\\n(Making a better transcript)\"]\n    Redo -- \"Off / Skipped\" --> IsMl{\"3. Malayalam\\nrecording?\"}\n    Retranscribe --> IsMl\n    IsMl -- \"Yes\" --> Reader[\"IndicTrans2 200M Reader\\n(Malayalam -> segment_readings)\"]\n    IsMl -- \"No (EN / DE)\" --> Notes[\"4. Final Notes\\n(Gemma 4 E2B or Gemma 3 1B)\"]\n    Reader --> Notes\n    Notes --> Name[\"5. Auto-Name\\n(2-5 word title)\"]\n    Name --> Todos[\"6. To-Dos & Ideas\\n(Time resolver + LLM + Grounding)\"]\n    Todos --> Map[\"7. Mind Map\\n(Topics -> Themes & Summaries)\"]\n```\n\nCompact 1B language models (`Gemma 3 1B`) struggle to parse Malayalam script directly, while loading a 3.3 GB model (`Gemma 4 E2B`) on every voice note is too heavy when phone RAM is tight. Satori solves this with a dedicated **internal reading stage**:\n\n- **Visible transcript stays in Malayalam** : Your recording's**Transcript** tab displays the Malayalam script (`മലയാളം` ) produced by`IndicConformer` .\n- **Under-the-hood IndicTrans2 bridge** : Between*Lines* and*Notes* ,`:feature-reader` (`:lib-reader-onnx` ) runs**AI4Bharat IndicTrans2 Distilled 200M INT8** (`242 MB` , 3 ONNX graphs on the bundled ONNX Runtime`1.28.2` + SentencePiece`model.SRC` /`model.TGT` + IndicNLP normalization and Malayalam-to-Devanagari offset transliteration, beam size 5) to write internal English readings into Room (`segment_readings` , DB v13).\n- **Unified downstream synthesis** :**Notes** ,**Auto-naming** ,**To-dos & Ideas** , and**Mind Map** topics read`segment_readings` , giving Malayalam recordings the same English notes, date resolution, and grounding quality as English recordings.\n- **Idle backfill (`ReadingBackfill`)** : Malayalam recordings that do not yet have` segment_readings` are quietly upgraded when the phone is idle, without overwriting any title, note, or to-do edited by the owner.\n\n- **Open To-Dos vs. Suggested Inbox (`TodoCapture`)** :\n  - Explicit reminders (`explicit` ), first-person promises (`commitment` ), and recordings made in the**To-do** category go straight to your**To do** list on Home (`TodoStatus.OPEN` ) and schedule an exact Android alarm (`AndroidReminderAlarm` , with**Done** and**Snooze 1 hr** notification actions).\n  - Tasks asked of you by someone else (`asked` ), implied tasks (`inferred` ), and`appointment` items land in the**`N suggested`** review sheet (` TodoSuggestionsSheet` ) where you can**Keep** ,**Dismiss** ,**Move to ideas** , or**Keep all** .\n- Explicit reminders (\n- **Ideas (`IdeasScreen`)** :\n  - Wishes or suggestions mentioned in a recording (*\"there should be an option to...\"* ,*\"it would be nice if...\"* ) and recordings made in the**Idea** category are collected on the**Ideas** page (`%d ideas, %d new` on Home).\n  - Ideas link back to their source recording and segment, outlast deleted recordings (*Without a recording* ), and convert into scheduled to-dos in one tap (`Make it a to-do` ).\n- Wishes or suggestions mentioned in a recording (\n\n- **Two-level knowledge graph centered on `You`** :\n  - **Themes (`MindNodeKind.THEME`)** : Recurring subjects across your recordings (e.g.,*Journaling* ,*Local LLMs & AI* ,*Deep Work* ). When multiple recordings link to a theme,`RefreshThemeSummariesUseCase` writes a 2–4 sentence cross-recording summary of what is known and decided (newest recording wins when facts change).\n  - **Topics (`MindNodeKind.TOPIC`)** : What an individual recording said about a theme (1–4 grounded words + up to 3 bullet points), linking directly back to the recording.\n- **Interactive Canvas & Accessible List** : Toggle between the 2D radial graph (**Show as map** ) and a structured list (**Show as list** ), filter by**Core** (pinned + top themes),**Recent** (last 7 days), or**All** , and batch-index older recordings via**Map N older recordings** .\n\n- **Audio player & seek-to-line** : Play/pause, scrub bar, file size &`Compressed` badge, and tap any transcript line (`Play from here` ) to jump playback to that segment's timestamp.\n- **Transcribe again** : Re-run speech recognition on any saved recording's audio with any installed model (**Parakeet v3** ,**Parakeet v2** ,**Cohere Transcribe** , or**Malayalam (AI4Bharat)** ).\n- **Automatic AAC compression & retention (`AudioRetentionJob`)** : Configure**Compress older audio** (` After N days` , shrinking`~2 MB/min` WAV files to`~0.25 MB/min` AAC/M4A while keeping them playable and re-transcribable) and**Delete older audio** (`After N days` , removing audio while keeping transcripts, notes, to-dos, ideas, and mind-map links). Per-recording**Keep this audio** exempts important recordings.\n- **Offline GPS place naming (`places.bin`)** : Optional` Save the place` resolves a recording's starting GPS fix offline against a bundled GeoNames KD-tree (`app/src/main/assets/places.bin` , e.g.,`Berlin` or`Near Berlin` ) with zero network requests.\n\nModels are downloaded on demand inside the app (`Settings → Models and storage` and `Settings → Advanced`) and verified by byte size and SHA-256 (` ModelChecksums`) before use.\n\n| Model | Role | Languages | Size | Runtime | \n|---|---|---|---|---|\n| **Silero VAD** (`silero_vad.onnx` ) | Voice activity detection (bundled in APK assets; tunable pause length, max phrase, and threshold) | Language-agnostic | `1.8 MB` | ONNX Runtime `1.28.2` | \n| **Parakeet v3** (`PARAKEET_V3` ) | Default live streaming speech recognizer & *Transcribe again* (supports custom hotwords via`bpe.vocab` ) | English & German (multilingual TDT 0.6B v3 INT8) | `~670 MB` | `sherpa-onnx` | \n| **Parakeet v2** (`PARAKEET_V2_EN` ) | Optional *Better transcript after Stop* &*Transcribe again* for lower English WER | English | `~660 MB` | `sherpa-onnx` | \n| **Cohere Transcribe** (`COHERE_TRANSCRIBE` ) | Optional high-accuracy *Better transcript after Stop* &*Transcribe again* | English & German | `~2.9 GB` | `sherpa-onnx` | \n| **Malayalam (AI4Bharat)** (`INDICCONFORMER_ML` ) | Live streaming, post-stop second pass, and *Transcribe again* for Malayalam speech (`IndicConformer 120M INT8` ) | Malayalam ( `ml` ) | `~140 MB` | `sherpa-onnx` | \n\n| Model | Role | Direction | Size | Runtime | \n|---|---|---|---|---|\n| **IndicTrans2 Distilled 200M INT8** | Internal post-stop reading stage ( `segment_readings` ) so downstream LLM steps read English instead of raw Malayalam script | Malayalam → English ( `mal_Mlym` →`eng_Latn` ) | `~242 MB` | ONNX Runtime `1.28.2` C API + SentencePiece | \n\n| Model | Setting Name | Role | Size | Quantization | \n|---|---|---|---|---|\n| **Gemma 3 1B IT** | **Standard** (default) | Live notes, post-stop notes, auto-naming, to-dos & ideas, live/post-stop EN↔DE translation, and mind map | `~1.0 GB` | `Q8_0` GGUF | \n| **Gemma 3 1B IT** | **Efficient** | Lower-memory alternative for live and post-stop tasks | `~650 MB` | `IQ4_NL` GGUF | \n| **Qwen 3.5 0.8B** | **Qwen 3.5 0.8B** | Compact alternative model in *Advanced settings* | `~870 MB` | `Q8_0` GGUF | \n| **Gemma 4 E2B IT** | **Gemma 4 E2B** | Optional higher-capacity model dedicated to *AI for finished recordings* (post-stop notes, naming, to-dos, and mind map when free RAM permits) | `~3.3 GB` | `Q4_0` QAT GGUF | \n\n- **Paced Pre-Faulting (`ModelLoadPacing`)** : Custom patches on` llama.cpp` (`0001-load-progress-bytes.patch` ,`0002-map-populate-switch.patch` ,`0003-mapped-hook.patch` ) disable`MAP_POPULATE` and pre-fault GGUF pages at a capped`120 MB/s` (`0 MB/s` while a recording is active) so disk reads never starve the UI thread or audio capture buffer.\n- **Page-Cache & Arena Reclamation** : Releasing a model calls`madvise(MADV_PAGEOUT)` /`posix_fadvise(POSIX_FADV_DONTNEED)` on mapped weight pages and purges native allocator arenas.\n- **Live `/proc/meminfo` Guards (`MemoryFloor`, `AnswerFloor`, `ParseRoom`)** : Before loading` Cohere Transcribe` ,`Gemma 4 E2B` , or`IndicTrans2` , Satori checks`MemAvailable` against model-specific headroom floors and falls back gracefully (e.g., from`Gemma 4 E2B` to`Gemma 3 1B` ) when memory is tight.\n- **Disk-Cached System Prompts (`forgetPromptCache`)** : All note, to-do, and mind-map system prompts are static and placeholder-free (`strings_grille_ai.xml` ,`strings_grille_todo_ai.xml` ,`strings_grille_mindmap_ai.xml` ), allowing`:lib-llama-android` to serialize their evaluated KV state to disk once and reload it across sessions without re-evaluating the system prompt on every recording.\n\nSatori is organized as a 10-module Gradle project with strict Clean Architecture boundaries (`:domain` is pure Kotlin with zero Android dependencies):\n\n```\nflowchart TD\n    app[\":app\\nCompose Grille UI, Cover Screen, QuickKey, Foreground Services\"]\n    presentation[\":presentation\\nViewModels, RecordingFinisher, HomeStrip, MindMap, Audio/Todo/Idea State\"]\n    domain[\":domain\\nUse Cases, Entities, Time Resolver, Malayalam Reading Prep, Grounding\"]\n    data[\":data\\nRoom DB (v13), Model Downloads, Memory Pacing, Offline Places, Retention\"]\n    feature_stt[\":feature-stt\\nStreaming & Offline STT + Silero VAD\"]\n    feature_llm[\":feature-llm\\nGGUF Inference, Prompt Cache & Grammar Constrained Output\"]\n    feature_reader[\":feature-reader\\nIndicTrans2 200M Malayalam-to-English Reader\"]\n    lib_sherpa[\":lib-sherpa-onnx\\nJNI Bridge to sherpa-onnx + ONNX Runtime 1.28.2\"]\n    lib_llama[\":lib-llama-android\\nCMake / JNI Bridge to llama.cpp (ARMv8.0 - ARMv9.2)\"]\n    lib_reader[\":lib-reader-onnx\\nCMake / JNI Bridge to ORT C API + SentencePiece\"]\n\n    app --> presentation\n    app --> domain\n    app --> data\n    app --> feature_stt\n    app --> feature_llm\n    app --> feature_reader\n\n    presentation --> domain\n    data --> domain\n\n    feature_stt --> domain\n    feature_stt --> data\n    feature_stt --> lib_sherpa\n\n    feature_llm --> domain\n    feature_llm --> data\n    feature_llm --> lib_llama\n\n    feature_reader --> domain\n    feature_reader --> data\n    feature_reader --> lib_reader\n    lib_reader --> lib_sherpa\n```\n\n| Module | Responsibility | \n|---|---|\n| [`:app`](https://github.com/TinkeringDao/satori/blob/main/app) | Jetpack Compose UI ( `Grille` ),`MainActivity` (`singleTask` cover/inner handoff),`QuickKeyActivity` ,`RecordingService` ,`LlmProcessingService` , and Hilt DI wiring. | \n| [`:presentation`](https://github.com/TinkeringDao/satori/blob/main/presentation) | `MainViewModel` ,`RecordingFinisher` ,`SessionsViewModel` ,`SessionDetailsViewModel` ,`RecordingAudioViewModel` ,`MindMapViewModel` ,`IdeasViewModel` ,`SettingsViewModel` , and`FirstRunCoordinator` state flows. | \n| [`:domain`](https://github.com/TinkeringDao/satori/blob/main/domain) | Pure Kotlin business logic: `FinishRecordingUseCase` ,`ExtractTodosUseCase` ,`TodoTimeResolver` ,`TodoGrounding` ,`MapRecordingUseCase` ,`RefreshThemeSummariesUseCase` ,`com.satori.domain.reading` Malayalam preprocessing, and repository interfaces. | \n| [`:data`](https://github.com/TinkeringDao/satori/blob/main/data) | Room database ( `AppDatabase` v13: sessions, segments,`segment_readings` , insights, to-dos, ideas, mind nodes/edges, categories), resumable Hugging Face downloader,`ModelLoadPacing` ,`AudioRetentionJob` (WAV→M4A compression & cleanup), and offline`places.bin` geocoder. | \n| [`:feature-stt`](https://github.com/TinkeringDao/satori/blob/main/feature-stt) | `SherpaOnnxDataSource` managing Silero VAD segmentation, streaming`Parakeet v3` /`IndicConformer` recognition, custom hotword boosting, and offline re-transcription (`Parakeet v2` ,`Cohere Transcribe` ). | \n| [`:feature-reader`](https://github.com/TinkeringDao/satori/blob/main/feature-reader) | `OnnxReaderDataSource` driving the 3-session IndicTrans2 200M beam-search translator for Malayalam recordings. | \n| [`:feature-llm`](https://github.com/TinkeringDao/satori/blob/main/feature-llm) | `LlamaCppDataSource` managing GGUF loading, system-prompt KV disk cache, GBNF grammar enforcement, and token streaming. | \n| [`:lib-sherpa-onnx`](https://github.com/TinkeringDao/satori/blob/main/lib-sherpa-onnx) | Prebuilt `arm64-v8a`` libsherpa-onnx-jni.so` and`libonnxruntime.so` (`1.28.2` ) with Kotlin/JNI bindings. | \n| [`:lib-reader-onnx`](https://github.com/TinkeringDao/satori/blob/main/lib-reader-onnx) | Native C++ JNI bridge ( `reader_jni.cpp` ) linking against`:lib-sherpa-onnx` 's`libonnxruntime.so` (`OrtGetApiBase` ) and static SentencePiece (`model.SRC` /`model.TGT` ). | \n| [`:lib-llama-android`](https://github.com/TinkeringDao/satori/blob/main/lib-llama-android) | Native CMake build of `llama.cpp` compiling per-microarchitecture ARM64 libraries (`armv8.0` through`armv9.2` with dotprod, i8mm, and FP16 acceleration) loaded dynamically at runtime via`/proc/cpuinfo` detection. | \n\n- **JDK 17**\n- **Android SDK** : Platform`android-35` (compile/target SDK 35,`minSdk` 29), Build-Tools`34.0.0`\n- **Android NDK** :`29.0.13113456` and**CMake**`3.31.6+` (for`:lib-llama-android` and`:lib-reader-onnx` )\n- **Git submodules** :`third_party/llama.cpp` and`third_party/sentencepiece` must be initialized before building.\n\n```\n# Initialize native submodules (llama.cpp and sentencepiece)\ngit submodule update --init --recursive\n\n# Run unit tests across all modules (4,000+ unit tests)\n./gradlew testDebugUnitTest\n\n# Run Android Lint checks\n./gradlew lintDebug\n\n# Build the debug APK\n./gradlew assembleDebug\n```\n\nThe compiled debug APK is written to `app/build/outputs/apk/debug/app-debug.apk`.\n\n- [`GLOSSARY.md`](https://github.com/TinkeringDao/satori/blob/main/GLOSSARY.md) — Domain, hardware, and on-device inference terminology across the codebase.\n- [`docs/GRILLE_DESIGN.md`](https://github.com/TinkeringDao/satori/blob/main/docs/GRILLE_DESIGN.md) — Complete specification of the`Grille` visual system, color tokens, typography, and cover/inner screen layouts.\n- [`docs/QUICK_KEY.md`](https://github.com/TinkeringDao/satori/blob/main/docs/QUICK_KEY.md) — Hardware power-key double-press (`com.motorola.mykey` ) integration and lock-screen capture behavior.\n- [`docs/MODEL_UX_SPEC.md`](https://github.com/TinkeringDao/satori/blob/main/docs/MODEL_UX_SPEC.md) — First-run onboarding, background download state machine, storage checks, and`HomeStrip` nudges.\n- [`docs/PRIVACY_AND_TERMS.md`](https://github.com/TinkeringDao/satori/blob/main/docs/PRIVACY_AND_TERMS.md) — Privacy architecture and local-only data storage guarantees.\n- [`docs/THIRD_PARTY_NOTICES.md`](https://github.com/TinkeringDao/satori/blob/main/docs/THIRD_PARTY_NOTICES.md) — Licenses and attributions for bundled libraries, fonts, GeoNames data, and downloadable models.", "url": "https://wpnews.pro/news/satori-offline-android-voice-notes-with-on-device-stt-and-local-llms", "canonical_source": "https://github.com/TinkeringDao/satori", "published_at": "2026-11-10 21:04:18+00:00", "updated_at": "2026-11-10 21:22:29.956339+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-tools", "ai-products", "natural-language-processing"], "entities": ["Satori", "NVIDIA", "Parakeet v3", "Cohere Transcribe", "AI4Bharat", "Gemma 3 1B", "Qwen 3.5 0.8B", "Motorola razr 70 plus"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/satori-offline-android-voice-notes-with-on-device-stt-and-local-llms", "markdown": "https://wpnews.pro/news/satori-offline-android-voice-notes-with-on-device-stt-and-local-llms.md", "text": "https://wpnews.pro/news/satori-offline-android-voice-notes-with-on-device-stt-and-local-llms.txt", "jsonld": "https://wpnews.pro/news/satori-offline-android-voice-notes-with-on-device-stt-and-local-llms.jsonld"}}