Add native Android app scaffold (M0): whisper.cpp engine via JNI
- android/: Gradle/Kotlin project (AGP 9.4, Compose, NDK 27.1), monorepo subdir as planned; whisper.cpp v1.9.3 vendored via pinned fetch script - core/whisper: JNI wrapper (beam size, threads, language) + WhisperEngine Kotlin API mirroring the desktop engine contract - app (M0 scope): in-app GGML model download from Hugging Face, engine load, WAV picker with resampling, on-device transcription, share sheet - build validated: assembleDebug OK, libwhisper_jni.so + ggml packaged
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# MeetRec for Android
|
||||
|
||||
Native Android app with the same functionality as the desktop meetrec:
|
||||
record meetings and transcribe them on-device with Whisper. Nothing leaves
|
||||
the phone — no cloud, no telemetry.
|
||||
|
||||
Status: **M0 (engine proof)** — the app can download a GGML model, load it
|
||||
via JNI (whisper.cpp, CPU/NEON) and transcribe a picked WAV file. Recording,
|
||||
live transcript, and output files arrive in later milestones (see the
|
||||
milestone plan in the project docs).
|
||||
|
||||
## Requirements
|
||||
|
||||
- Android Studio (or: SDK Platform 36, Build Tools 36, NDK 27.1, CMake 3.22.1)
|
||||
- JDK 17+
|
||||
- Device running Android 10+ (developed against a Fairphone 6 / Snapdragon
|
||||
7s Gen 3, Android 15+)
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
cd android
|
||||
./tools/fetch-whisper.sh # vendors whisper.cpp v1.9.3 into third_party/
|
||||
./gradlew :app:assembleDebug # or open the android/ folder in Android Studio
|
||||
adb install -r app/build/outputs/apk/debug/app-debug.apk
|
||||
```
|
||||
|
||||
`third_party/whisper.cpp` is gitignored — the fetch script pins the exact
|
||||
release tag so the JNI layer never breaks on upstream churn.
|
||||
|
||||
## Test on device (M0)
|
||||
|
||||
1. Launch **MeetRec**, pick a model (`tiny` is fine for a first test) and tap
|
||||
**Download** (model comes from Hugging Face; tiny is ~75 MB).
|
||||
2. Tap **Load engine**.
|
||||
3. Tap **Pick WAV file** and choose a 16 kHz mono WAV for best results
|
||||
(other PCM WAVs are resampled automatically).
|
||||
4. Tap **Transcribe** — segments with timestamps appear; share via the
|
||||
share sheet.
|
||||
|
||||
Expect roughly realtime transcription with `tiny`/`base` on the
|
||||
Fairphone 6's CPU; `small` is noticeably slower — use it for final passes
|
||||
only (the live/final split comes with the recorder milestones).
|
||||
|
||||
## Performance notes
|
||||
|
||||
- The engine runs on CPU via NEON, using up to 4 threads.
|
||||
- GPU/NPU acceleration (e.g. Snapdragon NPU via the QNN backend) is a
|
||||
stretch goal, not wired up yet.
|
||||
|
||||
## Module layout
|
||||
|
||||
```
|
||||
app/ Compose UI (model download, WAV picker, transcript view)
|
||||
core/whisper/ whisper.cpp JNI wrapper: CMake build + LibWhisper.kt +
|
||||
WhisperEngine.kt (the on-device transcription API)
|
||||
tools/ fetch-whisper.sh — vendor the pinned whisper.cpp release
|
||||
```
|
||||
|
||||
Models live in the app's private storage (`filesDir/models`), shared files
|
||||
with the desktop app's `~/.cache/meetrec/whisper-cpp` naming
|
||||
(ggml-tiny.bin … ggml-large-v3.bin).
|
||||
Reference in New Issue
Block a user