A MIDI virtual pipe organ for Android.
Plug any MIDI keyboard in through an OTG cable and play.
MagnusOrgue turns an Android phone into a small, no-fuss virtual organ. There's no DAW, no patch editor, no cloud account — you open the app, you hear an organ. If you own a "mute" MIDI controller, connect it with a USB OTG cable and it just works, no configuration required.
The whole point is low latency and zero friction. Everything else is secondary.
- 🎹 Monitor keyboard — five octaves across the top: mirrors what you play over MIDI, touchable (with glissando) when no keyboard is around
- 🔌 USB MIDI via OTG — automatic plug-and-play detection, hotplug safe, no permission dialogs
- 🎛️ Eleven real stops — 8 manual + 3 pedal ranks from the Giubiasco sample set by Piotr Grabowski, bundled with his kind permission; combinable like real ranks, grouped by division on a drawknob console
- 🎚️ Tremulant and Ottava Bassa coupler — wind wobble and sub-octave coupling, plus a General Cancel piston
- 🎯 Four combination pistons — tap to recall a registration, long-press to store it; everything survives restarts
- 🎼 Transposition and sustain pedal — ±6 semitones, and CC 64 works the way your keyboard expects
- ⚡ Low-latency audio — native C++ engine on top of Oboe, targeting < 20 ms
- 🎹 32-voice polyphony — big chords with both hands, no crackles
- 🔒 No permissions, no network, no analytics — it's an instrument, not a data broker
| Layer | Tech |
|---|---|
| UI | Kotlin + Jetpack Compose (custom Canvas keyboard) |
| MIDI | android.media.midi (MidiManager) |
| Audio | C++ / NDK with Oboe, sampled pipes (Giubiasco) |
| Bridge | A deliberately tiny JNI surface (ten small functions) |
| Build | Gradle (Kotlin DSL) + CMake |
Minimum SDK is 26 (Android 8.0). No sensitive permissions, no network access, no analytics.
Design docs live in /docs:
| Doc | Contents |
|---|---|
| 01-overview.md | Product vision, MVP scope, success criteria |
| 02-features.md | Full feature list with priorities |
| 03-architecture.md | Stack, module structure, JNI interface, threading |
| 04-midi.md | MIDI over OTG: connection flow, message parsing, edge cases |
| 05-audio.md | Audio engine: synthesis approach, latency budget, real-time rules |
| 06-ui-ux.md | Screens, keyboard component, states and feedback |
| 07-roadmap.md | Build phases — each one ends runnable on a phone |
| 08-testing.md | Testing on a real device: adb, MIDI checklists, latency checks |
Requirements: JDK 17+ and the Android SDK with NDK + CMake (a local.properties
pointing at your SDK). Then:
The organ samples are not in the repo (they belong to the sample set's author). Import them once from a local GrandOrgue set:
python3 tools/import_ranks.py "~/Documents/GrandOrgue/Organs/Giubiasco_GrandOrgue"./gradlew assembleDebug # build the APK
./gradlew installDebug # build and install on a connected phone
./gradlew test # run the unit tests (MIDI parser etc.)
adb logcat -s MagnusOrgue # tail the app logsTip: pair the phone over Wi-Fi adb (Developer options → Wireless debugging), because the USB port will be occupied by the OTG cable and the MIDI keyboard.
MagnusOrgue is free software, released under the GNU General Public License v3.0. You can redistribute it and/or modify it under the terms of the GPL as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

