Material Design 3 UI for ViPER4Android FX. Full feature set of the ViPER4Android DSP engine with a modern interface.
FET Compressor
ViPER Bass (Natural / Pure Bass+ / Subwoofer)
AnalogX
ViPER-DDC (Digital Device Correction)
Dynamic EQ (up to 10 bands, per-band threshold/attack/release)
Convolver (IRS impulse response loading)
Dynamic System (headphone virtualization)
Auditory System Protection (Cure crossfeed)
Driver Version 7 times in Settings)What is Global Mode?
Creates a single AudioEffect on session ID 0 (the global mix). The Android audio framework routes all audio through session 0, so one effect instance processes everything. This is the simplest and most compatible mode.
What is Per-App Mode?
Creates a separate AudioEffect for each audio player's session ID. The DSP processes each app's audio independently. Requires either root or installation as a privileged system app (see below).
Why does Per-App Mode require root (or a system-app install)?
On modern Android (API 34+ / Android 14+), the framework no longer broadcasts
OPEN_AUDIO_EFFECT_CONTROL_SESSION, andAudioManager.getActivePlaybackConfigurations()returns anonymized session IDs (sessionId:0, u/pid:-1/-1) to ordinary apps. The app usesAudioPlaybackCallbackto detect playback state changes, then needs a privileged path to recover the real session ID. Two paths are supported:
- Root (default): the real session ID is read via
su -c "dumpsys audio".- Privileged system app (no root): if the app is installed under
/system/priv-appand granted theMODIFY_AUDIO_ROUTINGpermission, the framework returns the real (non-anonymized)sessionId/clientUiddirectly fromgetActivePlaybackConfigurations(), so no root and nodumpsysshell-out is needed. The app auto-detects this at runtime (the permission grant is the trigger) and prefers it over the root path.
How do I install as a privileged system app (per-app mode without root)?
Place the APK in
/system/priv-app/ViPER4Android/and add a privileged-permission allowlist so the OS grantsMODIFY_AUDIO_ROUTING:
xml <!-- /system/etc/permissions/privapp-permissions-viper4android.xml --> <?xml version="1.0" encoding="utf-8"?> <permissions> <privapp-permissions package="com.llsl.viper4android"> <permission name="android.permission.MODIFY_AUDIO_ROUTING"/> </privapp-permissions> </permissions>This is done for you when the app ships inside a ROM or a Magisk module that mounts it systemlessly. Without the allowlist entry the permission is silently denied (with
ro.control_privapp_permissions=enforce, the default), and the app falls back to the root path. No platform signature is required, priv-app placement satisfies theprivilegedhalf of thesignature|privilegedprotection level.Note that you may need allow the following SElinux rules for the app (as system app) to work:
sh allow priv_app servicemanager service_manager list allow priv_app viper_control_service service_manager find allow priv_app default_android_service service_manager find allow priv_app hal_audio_default binder { call transfer }
What is Per-Device Profile?
Each audio device (e.g., "Galaxy Buds Pro", "Airpods", "Speaker") keeps its own saved effect settings, loaded automatically on connect and saved when the app goes to the background. See Per-Device Profiles for details.
What is AIDL Mode? > Android 14+ introduced a new Audio HAL interface based on AIDL (Android Interface Definition Language), > replacing the legacy HIDL interface. The App automatically check which HAL your device using.
Presets are stored in the v2 grouped-JSON format (schemaVersion: 2.1):
v2.1 stores the raw semantic values that send to the DSP
{
"schemaVersion": 2.1,
"name": "My Preset",
"equalizer": { "enable": true, "bandCount": 10, "bands": [3.0, 2.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0], "presetId": null },
"dynamicEq": { "enable": false, "bandCount": 4, "freqs": [...], "gains": [...] },
"ddc": { "enable": false, "device": "" }
}
v2 is not compatible with the old flat v1 JSON or the legacy ViPER4Android XML presets. Two migration paths are available:
.v2.json file, then import it in v2.Command-line tool. For v1 JSON or legacy XML presets, use tools/convert_preset.py (Python 3.11+):
```bash
python3 tools/convert_preset.py preset.json --to 2.1 -o preset.v2.json
python3 tools/convert_preset.py preset.xml --to 2.1 -o preset.v2.json
python3 tools/convert_preset.py preset.v2.json -o preset.v2_1.json ```
The input format (v1 JSON vs. XML) and, for v1 JSON, the headphone/speaker namespace are auto-detected.
Missing fields are filled with the app defaults. Import the resulting .v2.1.json in the app.
[!NOTE] v2 no longer stores separate headphone and speaker copies inside a preset. A preset now holds a single unified effect state and is applied to a device through the per-device profile system.
Each audio output device keeps its own full effect profile. When you switch outputs, the app automatically loads the incoming device's profile, so your speaker, wired earphones, and each pair of Bluetooth buds all remember their own tuning.
The active output is detected from the Android audio routing API, and each device gets a stable deviceId:
speakerwired_headphonebt_<id> if unavailable)usb_<id>)Because Bluetooth and USB devices are keyed by their hardware address, two different pairs of buds are stored separately, and reconnecting the same device restores exactly its profile. The display name comes from the device's reported product name (e.g. "Galaxy Buds Pro"), with a type-based fallback ("Bluetooth A2DP", "USB Audio", ...).
ON_STOP) and on shutdown: the current settings are saved to the active device's profile.Open the Devices dialog to manage saved profiles. There you can save the current settings to a device, load a device's profile into the current settings, rename a device, or delete a profile. Deleting a profile removes its saved settings, the device gets a fresh profile the next time it connects.
This app may require root access for:
dumpsys (not needed when installed as a privileged system app, see Per-App Mode in the Q&A)logcat for driver diagnosticsPlease make sure the source of any modified APK is trustworthy to avoid any security risks.
Contributions are welcome. Open an issue or submit a pull request.
To help with translations, follow the template guide.
| 日期 | 榜单 | 排名 | 周期新增 | 总 STAR |
|---|