Releases: moWerk/asteroid-beatfork
Beatfork v1.5
Release Notes — v1.5
What's new since 1.0
This release is a complete overhaul of the BPM Detect page. Pages 1 (Metronome) and 2 (Tuning Fork) are unchanged.
Beat History Ring
The BPM detect page now renders a rotating dot history ring around the reference circle. Each beat spawns a dot at the 10:30 position that travels counter-clockwise over one full revolution. Auto-beat dots appear in the current pulse color. User tap dots appear in the adjacent palette color (pulseColors[colorIndex+1]) and their radial position encodes timing drift — inward means early, outward means late. Dots fade out over the final portion of their revolution so the entry zone stays uncluttered.
Under the hood, dots are managed by a 24-slot pre-allocated Repeater pool rather than createObject/destroy on every beat, eliminating the GC pressure that caused microstutter on slower watches. Both animations on each pooled dot support paused: beatOffsetLocked || !pageActive so they freeze during lock and stop running entirely when the page is off-screen.
Smarter Tap Detection
The tap algorithm now rejects outlier intervals that deviate more than 30% from the running 8-tap average. A single mistap is silently discarded — the dot still spawns so it's visible on the ring, but the BPM doesn't lurch. Two consecutive outliers are treated as an intentional tempo change and reset the window. Half-time and double-time jumps are detected as harmonics and trigger an immediate reset rather than waiting for two outliers, so switching from 120 to 60 BPM locks in within one or two taps.
Beat handover is now phase-aligned: when tapping stops and the auto BPM takes over, the first auto beat fires exactly one beat after the last user press, not at an arbitrary point in the timer countdown. This uses lastPressTime (finger-down) rather than lastTap (finger-up), removing the 30-50ms touch duration offset that previously made the handover feel late.
Stats Cycler
The "Tap" hint disappears after the first tap and is replaced by a stats label that cycles through six measurements on each click of the upper screen area:
- Consistency % (standard deviation of intervals)
- Precise BPM to one decimal place
- Last tap drift in ±ms
- Confidence (n of 8 taps in average)
- BPM spread min–max this session
- ms per beat
Stats are frozen on each tap and persist after tapping stops so they can be read between sequences.
Turntable Brake / Push / Lock
Three touch zones below the BPM label allow DJ-style beat offset adjustment without changing the stored BPM:
- Left 40% — brake: adds +10ms to the beat interval per tap
- Right 40% — push: subtracts 10ms per tap
- Center 20% — lock: freezes the beat timer entirely, all ring dots pause mid-travel like a held record. Releasing fires an immediate beat to restart the flow phase-locked
- A decay timer returns the offset to zero at 10ms per 80ms when unlocked
The offset is applied only inside beatTimer.onTriggered and never via a live binding, which avoids the Qt timer countdown reset that previously caused a 2-dot gap after each nudge.
Arc Indicators
Two arcs of five › characters flank the lower ring, animated as a flipper-board comet trail driven by indicatorPhase which advances on each beat rather than a free-running timer. Brake arc sits lower-left (205°–249°), push arc lower-right (158°–114°). The center pause icon brightens when lock is active.
Visual and Performance Polish
pulseSmallnow hard-cuts to full opacity on beat (no animation) and is held for half the beat interval via a Timer, giving a longer flash at low BPM and a shorter one at high BPM- Ripple rings now spawn at the
pulseSmallborder edge and expand outward, duration bound tomin(300, halfBeatMs)so they never overlap at high BPM - BPM label scale punch on tap: 1.0 → 1.3 → 1.0 in 90ms total
pulseSmalllights ononPressedfor zero-latency feedback, stays lit until the next auto beat fires the off timer- Auto dots suppressed when a user tap occurred within 15% of the beat interval, preventing a shadow dot from trailing each tap dot
- PageHeader fades out and is disabled during an active session, freeing the upper screen area for the stats cycler touch zone
- New 10-color palette sequenced so adjacent pairs are always complementary or split-complementary
--







Known limitations
- Stats cycler header touch zone requires the PageHeader to have faded — there is a brief moment after the first tap where the header is still visible and the touch zone has reduced height
- Beat offset (turntable) does not persist across app sessions by design
BeatFork 1.0
BeatFork 1.0
asteroid-beatfork-v1-0.mp4
New since 0.2
Good citizen features
- Edge swipe indicators on all pages signal available navigation directions
- Tuning Fork page and metronome tick button hidden automatically on devices without a speaker
- Display stays on automatically during any active output — metronome flash, sound, haptic, or tuning fork loop — and sleeps normally otherwise
Architecture
- Pages split into separate QML components (BpmDetectPage, MetronomePage, TuningForkPage) for maintainability and community review
- Sound assets reduced from 3s to 0.5s WAV files for smaller footprint and cleaner PulseAudio buffer handling
- 415Hz file duration corrected to 208 complete cycles to eliminate loop splice click
Full feature reference
Detect BPM
Tap anywhere on screen to detect tempo by measuring intervals between taps. A rolling average of up to eight taps produces a stable reading across the supported range of 40 to 208 BPM. Starting a new tap series after a pause automatically discards previous data. Each tap emits ripple rings and six sparkle rays from the pulse circle edge, and the BPM label pumps bright on each tap. A pulsing circle visualises the current BPM continuously between taps. The detected BPM is shared with the Metronome page and persisted across app restarts.
Metronome
A full-screen beat flash runs at the stored BPM, opt-in so it does not activate on first open. The page header fades while the flash is running to maximise lit pixels. Tempo is adjusted with a circular spinner. Four toggle buttons independently activate the beat flash, audible tick, haptic vibration, and pulse color cycling. Active buttons pulse in BPM rhythm in lockstep with the beat clock. The tick button is hidden automatically on devices without a speaker. All settings are persisted across app restarts.
Tuning Fork
Hidden automatically on devices without a speaker. Tap the frequency display to cycle through seven reference pitches: G4 (392 Hz), Ab4 (415 Hz), A4 Verdi (432 Hz), A4 Standard (440 Hz), A4 Orchestra (442 Hz), A4 High (444 Hz), and Bb4 (452 Hz). Tap the play button for a short preview. Hold to lock a continuous gapless loop that keeps playing until you tap to stop. The button emits ripple rings while playing and breathes gently while idle. The frequency label pulses while looping, visible even when your finger covers the button. The selected frequency is persisted across app restarts.
Sound file generation
All sound assets are generated using SoX and shipped as 16-bit mono PCM WAV files.
Metronome tick
sox -n -r 44100 -b 16 -c 1 tick.wav synth 0.025 tri 2000 fade h 0.002 0.025 0.008 vol 0.7Tuning fork tones (repeat for each frequency, adjust duration for whole cycle count)
sox -n -r 44100 -b 16 -c 1 440hz.wav synth 0.5 sine 440 vol -1dB
sox -n -r 44100 -b 16 -c 1 415hz.wav synth 0.5012 sine 415 vol -1dBBeatFork v0.2
BeatFork 0.2
Three tools, one wrist — tap, pulse, tune.
Tuning Fork — fully reworked
- Tap the play button for a 1-second preview, hold to lock a continuous gapless loop until you tap to stop
- Frequency display now shows the musical name of each pitch above the Hz value (G4, Ab4, A4 Verdi, A4 Standard, A4 Orchestra, A4 High, Bb4)
- Play button pulses with ripple rings while active and breathes gently while idle
- Label in the upper half pulses while looping — visible even when your finger covers the button
Metronome
- Full-screen beat flash is now opt-in — no surprise on first open
- Page header fades out while the flash is running to maximise lit pixels
- All four control buttons pulse in BPM rhythm when active, in lockstep with the beat clock
- Page background darkened for stronger flash contrast
BPM Detect
- Tap now emits ripple rings and six sparkle rays from the pulse circle edge
- BPM label pumps bright on each tap and fades back to resting opacity
- Beat animation runs independently and is no longer interrupted by tapping
Navigation
- Page swiping requires a more deliberate horizontal gesture — accidental swipes while scrolling the BPM tumbler are suppressed
Screen keepalive
- Display stays on automatically while metronome sound, haptic, or flash is active, or the tuning fork loop is locked
- Sleeps normally in all other states
Under the hood
- Per-page background colors with smooth crossfade on swipe
- Beat animations gated by settle timer — no flash bleed during page transitions
- All state survives page navigation without delegate recycling artifacts
BeatFork v0.1
First release of BeatFork, a metronome and tuning fork app for AsteroidOS.
Detect BPM — tap the screen to measure tempo by inter-tap interval averaging.
The circle pulses at the detected BPM continuously, staying in phase with your
rhythm even after you stop tapping.
Metronome — full-screen pulsing circle running at the shared BPM. Adjust tempo
with the circular spinner. Optional audible tick and haptic beat feedback,
toggleable independently.
Tuning Fork — tap to cycle through reference pitches at 392, 415, 432, 440,
442, 444 and 452 Hz. Tap the icon to play once, hold to loop.
BPM and frequency selection persist across app restarts.
Full Changelog: https://github.com/moWerk/asteroid-beatfork/commits/0.1