Commit 18b6979
fix(audio): async decode playback edge cases (#186)
* fix async decode playback edges
* fix(audio): restore snappy optimistic highlight on cold press
#152 deferred the cold-press highlight until decode succeeded, so the first
press of every sound in a session showed no feedback until decode completed —
against the snappy-UI doctrine (#111: keep the optimistic instant highlight,
never slow the click->play path).
Restore it: a cold cache miss claims `playing` and the pending now-playing
state immediately, then the async decode confirms the playhead on success. A
decode failure, or a sound removed mid-decode, now releases the optimistic
highlight through a shared owns-the-UI guard, so it is never left stuck on a
sound that produced no audio. The generation/terminal-event invariant is
preserved: a superseded older press never retakes a newer press's highlight.
Reviving the optimistic path also un-orphans now_playing::pending(), which
#152 had left as dead code.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(audio): stop orphaned voice on library reconcile; make command boundary testable
Two review follow-ups for #152, plus the test infrastructure they needed.
- reconcile_playback_with_library now sends StopVoice for the highlighted
sound when its library entry vanishes mid-play, instead of only clearing the
UI and leaving the engine to honk the removed sound to completion ("ghost
honk"). The highlighted voice id is the current play_generation, since only
the owning press holds the highlight.
- Add a test-only command tap to AudioHandle (the pipewire command channel
can't be drained synchronously, so no test could previously assert what
reached the engine). Pin the core invariant the PR is about: a cold press
fires exactly one Play when its decode lands, and a decode landing after
StopAll is stale and fires none.
- Extract AudioHandle + test_handle out of the over-budget engine.rs (927
lines) into a focused handle.rs (78), so the tap lands in a compliant file
and engine.rs shrinks rather than grows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* style: apply cargo fmt to audio module exports
Fixes the CI lint (cargo fmt --check) failure on this branch.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(app): stop stale same-id decodes consuming the new pending decode
A decode cancelled by StopAll/interrupt shares its sound id with a
re-press's fresh pending entry. Landing first, it consumed that entry:
a stale error cleared the new press's optimistic highlight and the real
decode result was then dropped on arrival, so the sound never played.
Pending entries are now consumed only by the task that owns them
(matching voice id); stale landings fall through and are dropped.
Codex review finding [P2] on PR #186.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(ui): keep the active sound's waveform envelope during PCM eviction
A late decode evicting the active sound's PCM under cache pressure also
removed its waveform envelope, blanking the visible waveform mid-play
even though the engine keeps playing from its own Arc. The active
sound's envelope is now exempt from eviction.
Codex review finding [P3] / CodeRabbit nitpick on PR #186.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(deny): ignore quick-xml RUSTSEC-2026-0194/0195 pending upstream bump
Both advisories are DoS-via-untrusted-XML in quick-xml < 0.41. The sole
consumer is wayland-scanner, a build-time proc-macro parsing vendored
Wayland protocol XML; no untrusted XML is parsed at runtime, so neither
issue is reachable in the shipped binary. wayland-scanner 0.31.10
(latest) still pins quick-xml ^0.39 — drop these ignores when it moves
to 0.41.
Closes #192.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(deps): bump anyhow to 1.0.103 (RUSTSEC-2026-0190)
anyhow 1.0.102 is flagged unsound (Error::downcast_mut UB after
Error::context); 1.0.103 is the patched release already on main.
Regenerates the Flatpak cargo-sources.json for the lock change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor(tests): split playback tests under the 400-line file cap
tests.rs hit 465 lines after the decode-ownership regressions landed.
Fixtures move to test_support.rs; warm-path, eviction, and library-
reconciliation tests move to cache_tests.rs; decode-ownership lifecycle
tests stay in tests.rs. No test behavior changes.
Addresses CodeRabbit review on PR #186.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor(tests): capture generation values instead of hardcoding literals
Addresses CodeRabbit nitpick on PR #186; keeps the concurrent-decode
tests resilient to generation-counter changes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci: retrigger checks (pull_request events for previous pushes were dropped)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent b4f71b7 commit 18b6979
11 files changed
Lines changed: 747 additions & 299 deletions
File tree
- src
- app
- playback
- audio
- ui
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
247 | 247 | | |
248 | 248 | | |
249 | 249 | | |
250 | | - | |
251 | | - | |
252 | | - | |
| 250 | + | |
| 251 | + | |
253 | 252 | | |
254 | 253 | | |
255 | 254 | | |
256 | 255 | | |
| 256 | + | |
257 | 257 | | |
258 | 258 | | |
259 | 259 | | |
| |||
446 | 446 | | |
447 | 447 | | |
448 | 448 | | |
| 449 | + | |
449 | 450 | | |
450 | 451 | | |
451 | 452 | | |
| |||
507 | 508 | | |
508 | 509 | | |
509 | 510 | | |
| 511 | + | |
510 | 512 | | |
511 | 513 | | |
512 | 514 | | |
| |||
699 | 701 | | |
700 | 702 | | |
701 | 703 | | |
702 | | - | |
703 | | - | |
704 | | - | |
705 | | - | |
706 | | - | |
707 | | - | |
708 | | - | |
709 | | - | |
710 | | - | |
711 | | - | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
712 | 712 | | |
713 | 713 | | |
714 | 714 | | |
| |||
812 | 812 | | |
813 | 813 | | |
814 | 814 | | |
| 815 | + | |
815 | 816 | | |
816 | 817 | | |
817 | 818 | | |
| |||
1006 | 1007 | | |
1007 | 1008 | | |
1008 | 1009 | | |
| 1010 | + | |
1009 | 1011 | | |
1010 | 1012 | | |
1011 | 1013 | | |
| |||
2012 | 2014 | | |
2013 | 2015 | | |
2014 | 2016 | | |
2015 | | - | |
2016 | | - | |
2017 | | - | |
2018 | | - | |
2019 | | - | |
2020 | | - | |
2021 | | - | |
2022 | | - | |
2023 | | - | |
2024 | | - | |
2025 | | - | |
2026 | | - | |
2027 | | - | |
2028 | | - | |
2029 | | - | |
2030 | | - | |
2031 | | - | |
2032 | | - | |
2033 | | - | |
2034 | | - | |
2035 | | - | |
2036 | | - | |
2037 | | - | |
2038 | | - | |
2039 | | - | |
2040 | 2017 | | |
2041 | 2018 | | |
2042 | 2019 | | |
| |||
2082 | 2059 | | |
2083 | 2060 | | |
2084 | 2061 | | |
2085 | | - | |
2086 | | - | |
2087 | | - | |
2088 | | - | |
2089 | | - | |
2090 | | - | |
2091 | | - | |
2092 | | - | |
2093 | | - | |
2094 | | - | |
2095 | | - | |
2096 | | - | |
2097 | | - | |
2098 | | - | |
2099 | | - | |
2100 | | - | |
2101 | | - | |
2102 | | - | |
2103 | | - | |
2104 | | - | |
2105 | | - | |
2106 | | - | |
2107 | | - | |
2108 | 2062 | | |
2109 | 2063 | | |
2110 | 2064 | | |
| |||
3325 | 3279 | | |
3326 | 3280 | | |
3327 | 3281 | | |
3328 | | - | |
3329 | | - | |
3330 | | - | |
3331 | | - | |
3332 | | - | |
3333 | | - | |
3334 | | - | |
3335 | | - | |
3336 | | - | |
3337 | | - | |
3338 | | - | |
3339 | | - | |
3340 | | - | |
3341 | | - | |
3342 | | - | |
3343 | | - | |
3344 | | - | |
3345 | | - | |
3346 | | - | |
3347 | | - | |
3348 | | - | |
3349 | | - | |
3350 | | - | |
3351 | | - | |
3352 | | - | |
3353 | | - | |
3354 | | - | |
3355 | | - | |
3356 | | - | |
3357 | | - | |
3358 | | - | |
3359 | | - | |
3360 | | - | |
3361 | | - | |
3362 | | - | |
3363 | | - | |
3364 | | - | |
3365 | | - | |
3366 | | - | |
3367 | | - | |
3368 | | - | |
3369 | | - | |
3370 | | - | |
3371 | | - | |
3372 | | - | |
3373 | | - | |
3374 | | - | |
3375 | | - | |
3376 | | - | |
3377 | | - | |
3378 | | - | |
3379 | | - | |
3380 | | - | |
3381 | | - | |
3382 | | - | |
3383 | | - | |
3384 | | - | |
3385 | | - | |
3386 | | - | |
3387 | | - | |
3388 | | - | |
3389 | | - | |
3390 | | - | |
3391 | | - | |
3392 | | - | |
3393 | | - | |
3394 | | - | |
3395 | | - | |
3396 | | - | |
3397 | | - | |
3398 | | - | |
3399 | | - | |
3400 | | - | |
3401 | | - | |
3402 | | - | |
3403 | | - | |
3404 | | - | |
3405 | | - | |
3406 | | - | |
3407 | | - | |
3408 | | - | |
3409 | | - | |
3410 | | - | |
3411 | | - | |
3412 | | - | |
3413 | | - | |
3414 | | - | |
3415 | | - | |
3416 | | - | |
3417 | 3282 | | |
0 commit comments