- Black (#0a0a0a) background, off-white (#f0ede8) text,
lime-yellow (#e8ff47) accent, monospace font throughout
- BPM number flashes to accent on each beat
- Pulse ring with expanding ripple and scaling center dot
- Linear progress bar sweeps across the bottom each interval
- Subtle scanline overlay for retro CRT effect
- START/STOP button inverts to accent when active
BeepGenerator: add 5ms attack / 10ms release envelope so the
waveform ramps in/out cleanly instead of cutting off mid-cycle,
which caused the audible click/distortion.
AudioEngine: replace postDelayed scheduling with a continuous
write loop — each iteration writes the full beep followed by
silence in 10ms chunks. This keeps the AudioTrack stream full
and eliminates underrun noise. onBeep callback fires on the
main thread just before each beep is queued.
PacerService: wire onBeep to increment beepTick (Compose state).
PacerScreen: replace the independent BPM timer with beepTick so
the pulse ring animation is driven by the actual audio callback,
eliminating the drift at slow paces.
PacerService owns AudioEngine and a PARTIAL_WAKE_LOCK so audio
survives screen lock and Doze during long walks. Foreground
notification shows current BPM and a Stop action button.
PacerViewModel becomes AndroidViewModel and communicates with
the service via intents, keeping AudioEngine off the UI process.
Service uses START_NOT_STICKY so it does not restart if killed.
Dark-themed Compose screen with:
- Large monospace BPM counter and pace slider (40-200 BPM)
- Six preset buttons (80/100/120/130/140/160 BPM)
- Volume slider with percentage readout
- Circular start/stop button with green pulse ring that
animates on each beat via a coroutine-driven LaunchedEffect
- PacerViewModel owns AudioEngine lifecycle so audio survives
configuration changes
BpmCalculator provides interval math (60000 / bpm) and volume
clamping (0.0-1.0). AudioEngine drives AudioTrack on a dedicated
HandlerThread, scheduling beeps via postDelayed for battery-
efficient background playback.
Audio focus is intentionally never requested so beeps play
alongside other apps without ducking (US-05).
Initial project structure with manifest configured for foreground
audio service, AudioTrack-based playback, and background operation.
Includes Gradle wrapper, dependency catalog, placeholder icons,
and build instructions for Arch Linux.