LUFS Generator for Android
Cross-compiled Rust binary that calculates LUFS (Loudness Units Full Scale) for audio files on Android using streaming audio decoders.
Prerequisites
- Android NDK (tested with 23.2.8568313)
- Rust toolchain
Build Steps
Step 1: Set environment variables
Step 2: Build Rust Binary
The binary will be at: target/aarch64-linux-android/release/lufsgen
Step 3: Deploy to Android
# or with adb
Step 4: Run on Android
# Calculate LUFS for a single file
# Scan a directory
# Save results to file
Usage
lufsgen <audio-file> Calculate LUFS for a single file
lufsgen <directory> Scan directory for audio files
lufsgen <file/dir> <output> Save results to file
Output Format
The binary outputs filename|lufs per line:
song.mp3|-12.5
track2.wav|-10.3
Supported Audio Formats
- MP3 (
.mp3) - WAV (
.wav) - AAC (
.aac,.m4a,.mp4) - OGG (
.ogg,.oga) - FLAC (
.flac)
How It Works
This project uses Symphonia, a pure Rust multimedia framework, to decode audio files. The streaming decoder:
- Auto-detects audio format from file content (not just extension)
- Decodes audio chunk-by-chunk (8192 samples per chunk)
- Feeds samples to EBU R128 loudness analyzer
- Returns the integrated LUFS value
This approach is memory-efficient and suitable for mobile devices.
Desktop Testing
Troubleshooting
Build fails
Make sure the NDK path is correct and the clang compiler exists:
Permission denied
Make the binary executable:
M4A/MP4 file fails with "Failed to detect audio format"
Some M4A files have metadata (moov atom) at the end of the file, which Symphonia cannot detect. Convert the file with FFmpeg to move metadata to the beginning:
The -c:a copy flag copies the audio without re-encoding (fast, no quality loss). The -movflags +faststart flag optimizes for streaming by moving the moov atom to the front.
Library Usage
This is also a library that can be used in other Rust projects:
use ;
// Check if file is supported
if is_audio_file
See lib.rs for the full API documentation.