Skip to content

Peterc3-dev/retune432-android

Repository files navigation

Retune432 — Android

Pitch-shift audio files from A440 to A432 Hz (432/440 = 0.9818... ratio, ~31.77 cents down). Preserves tempo, metadata, and original format. Android port of retune432.py.

Features

  • Pitch shift via ffmpeg rubberband filter (primary) or asetrate+aresample (fallback)
  • Batch processing — select multiple files at once
  • Format support — mp3, flac, wav, ogg, aac, m4a
  • Metadata preservation — ID3v2, Vorbis comments, FLAC tags carried through
  • Skip duplicates — won't re-convert files already in output folder
  • Material Design 3 UI with dynamic color (Android 12+)
  • Foreground service with progress notification
  • Output to Music/Retune432/ on device storage

Build

Prerequisites

  • Android Studio Ladybug (2024.2.1) or newer
  • JDK 17
  • Android SDK 35
  • Kotlin 2.1.0

Steps

# Clone
cd ~/retune432-android

# Open in Android Studio
studio .

# Or build from command line (requires Android SDK + ANDROID_HOME set)
./gradlew assembleDebug

# Install on connected device
./gradlew installDebug

The first build will download ffmpeg-kit-full (~80MB) — this bundles the full ffmpeg binary with all codecs including rubberband.

Gradle wrapper

If gradlew is missing, generate it:

gradle wrapper --gradle-version 8.9

Project Structure

retune432-android/
├── app/
│   ├── build.gradle.kts              # App module build config
│   ├── proguard-rules.pro            # Keep ffmpeg-kit classes
│   └── src/main/
│       ├── AndroidManifest.xml       # Permissions, service, activity
│       ├── java/com/retune432/app/
│       │   ├── Retune432App.kt       # Application class, notification channel
│       │   ├── MainActivity.kt       # Entry point, Compose host
│       │   ├── service/
│       │   │   └── ConversionService.kt  # Foreground service for batch conversion
│       │   ├── ui/
│       │   │   ├── theme/Theme.kt    # MD3 theme with dynamic color
│       │   │   ├── screens/MainScreen.kt # Main UI: file picker + progress + log
│       │   │   └── components/
│       │   │       ├── FileChip.kt       # Selected file chip with remove
│       │   │       └── ConversionLogItem.kt  # Result row in log
│       │   └── util/
│       │       └── AudioConverter.kt # Core conversion logic (rubberband + fallback)
│       └── res/
│           ├── drawable/ic_music_note.xml
│           ├── values/strings.xml
│           ├── values/themes.xml
│           └── xml/file_paths.xml
├── build.gradle.kts                  # Root build file
├── settings.gradle.kts               # Project settings
├── gradle.properties                 # JVM args, AndroidX
├── gradle/
│   ├── libs.versions.toml            # Version catalog
│   └── wrapper/gradle-wrapper.properties
├── .gitignore
└── README.md

Architecture

  • AudioConverter — stateless converter object. Two-tier strategy:
    1. rubberband=pitch=0.9818 (high quality, preserves formants)
    2. asetrate + aresample fallback if rubberband unavailable
  • ConversionService — foreground service running conversions off the main thread. Exposes a StateFlow<ConversionState> consumed by the UI.
  • MainScreen — single-screen Compose UI. File picker → convert button → progress bar → results log.

Permissions

Permission Why When
READ_MEDIA_AUDIO (API 33+) Read audio files File selection
READ_EXTERNAL_STORAGE (API <33) Same, legacy File selection
FOREGROUND_SERVICE Run conversion in background During conversion
POST_NOTIFICATIONS (API 33+) Show progress notification During conversion

License

Same as retune432.py — MIT.

About

Android app to batch-convert audio from A440 to A432 Hz with metadata preservation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors