Reels are now NAB-style: a metal flange with three rotating rounded-triangular bobbin holes and a hub, instead of chariot-wheel spokes. Tape runs under tension as straight lines from each reel down to a rounded-rectangle playhead between and below them (the top tape line is gone). The four controls are vintage round knobs in a row — wow, flutter, hiss, wow-sync — replacing the sliders/stepper. Each knob is weighted so all four are visible (the shared Knob's internal fillMaxWidth text had let the first one swallow the row), and Knob gains an optional knobSize (default 44 dp, so other editors are unchanged) which the tape knobs set to 58 dp. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
138 lines
5.1 KiB
Kotlin
138 lines
5.1 KiB
Kotlin
// Build configuration for the single application module. This is where we turn
|
|
// on Compose, set the min/target Android versions, and list dependencies.
|
|
|
|
plugins {
|
|
alias(libs.plugins.android.application)
|
|
alias(libs.plugins.kotlin.android)
|
|
alias(libs.plugins.kotlin.compose)
|
|
}
|
|
|
|
android {
|
|
namespace = "space.rcmd.android.sizzle"
|
|
compileSdk = 34
|
|
|
|
// Native (Oboe) low-latency output backend; see src/main/cpp.
|
|
// NDK r27+ builds native libs 16 KB-page-aligned by default and ships a
|
|
// 16 KB-aligned libc++_shared.so (required for Android 15 / Google Play).
|
|
ndkVersion = "27.2.12479018"
|
|
|
|
defaultConfig {
|
|
applicationId = "space.rcmd.android.sizzle"
|
|
// minSdk 26 (Android 8.0) is the floor for the native MIDI API
|
|
// (android.media.midi) and AAudio low-latency audio we rely on.
|
|
minSdk = 26
|
|
targetSdk = 34
|
|
versionCode = 35
|
|
versionName = "0.13.2"
|
|
|
|
// We provide our own instrumentation runner if/when tests are added.
|
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
|
|
externalNativeBuild {
|
|
cmake { arguments += "-DANDROID_STL=c++_shared" }
|
|
}
|
|
}
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
path = file("src/main/cpp/CMakeLists.txt")
|
|
version = "3.22.1"
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
release {
|
|
// Shrinking is off by default so newcomers get readable stack traces.
|
|
// Flip to true once the app stabilises.
|
|
isMinifyEnabled = false
|
|
proguardFiles(
|
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
"proguard-rules.pro",
|
|
)
|
|
}
|
|
|
|
// A realistic-performance "staging" variant for testing UI responsiveness
|
|
// on-device. The `debug` build is `debuggable = true`, which makes ART run
|
|
// the app un-optimised and makes Compose several times slower — so measuring
|
|
// UI "snappiness" on a debug build is misleading. This variant flips
|
|
// debuggability off (the single biggest perf lever) while reusing the debug
|
|
// signing key, so it still installs without a release keystore. R8/shrinking
|
|
// stays off to avoid needing JNI/Compose keep-rules for now.
|
|
create("staging") {
|
|
initWith(getByName("debug"))
|
|
isDebuggable = false
|
|
isJniDebuggable = false
|
|
signingConfig = signingConfigs.getByName("debug")
|
|
matchingFallbacks += "debug"
|
|
}
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility = JavaVersion.VERSION_17
|
|
targetCompatibility = JavaVersion.VERSION_17
|
|
}
|
|
|
|
kotlinOptions {
|
|
jvmTarget = "17"
|
|
}
|
|
|
|
buildFeatures {
|
|
compose = true
|
|
prefab = true // exposes the Oboe AAR's native headers/lib to CMake
|
|
}
|
|
|
|
packaging {
|
|
resources.excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
|
}
|
|
}
|
|
|
|
// Give the release APK a predictable, versionCode-stamped name so it drops straight
|
|
// into the private F-Droid repo: space.rcmd.android.sizzle_<versionCode>.apk. Uses
|
|
// the legacy variant API (the Kotlin-DSL `android {}` receiver doesn't expose it).
|
|
(extensions.getByName("android") as com.android.build.gradle.AbstractAppExtension)
|
|
.applicationVariants.all {
|
|
if (buildType.name == "release") {
|
|
val vc = versionCode
|
|
outputs.all {
|
|
(this as com.android.build.gradle.internal.api.BaseVariantOutputImpl)
|
|
.outputFileName = "space.rcmd.android.sizzle_$vc.apk"
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation(libs.androidx.core.ktx)
|
|
implementation(libs.androidx.lifecycle.runtime.ktx)
|
|
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
|
implementation(libs.androidx.activity.compose)
|
|
|
|
// Compose UI toolkit — the BOM keeps every Compose artifact on one version.
|
|
implementation(platform(libs.androidx.compose.bom))
|
|
implementation(libs.androidx.compose.ui)
|
|
implementation(libs.androidx.compose.ui.graphics)
|
|
implementation(libs.androidx.compose.ui.tooling.preview)
|
|
implementation(libs.androidx.compose.foundation)
|
|
implementation(libs.androidx.compose.material3)
|
|
implementation(libs.androidx.compose.material.icons.extended)
|
|
debugImplementation(libs.androidx.compose.ui.tooling)
|
|
|
|
// Background playback + media-style notification transport controls.
|
|
implementation(libs.androidx.media3.session)
|
|
implementation(libs.androidx.media3.common)
|
|
|
|
// Persistence for settings & themes.
|
|
implementation(libs.androidx.datastore.preferences)
|
|
|
|
// Coroutines for the audio/sequencer background work.
|
|
implementation(libs.kotlinx.coroutines.android)
|
|
|
|
// Oboe: low-latency native audio (AAudio) — the native output backend.
|
|
// 1.9.3+ ships 16 KB-page-aligned .so files (required by Android 15 / Play).
|
|
implementation("com.google.oboe:oboe:1.10.0")
|
|
|
|
// JVM unit tests for the pure model/io logic (no device needed).
|
|
testImplementation("junit:junit:4.13.2")
|
|
// Virtual-time coroutine testing (drives the input hold-to-repeat schedule).
|
|
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
|
|
}
|