Skip to content

fix(akouo): playback-engine correctness (real seek, decode-failure signaling) - #485

Merged
forkwright merged 1 commit into
mainfrom
fix/akouo-playback-engine
Jul 1, 2026
Merged

fix(akouo): playback-engine correctness (real seek, decode-failure signaling)#485
forkwright merged 1 commit into
mainfrom
fix/akouo-playback-engine

Conversation

@forkwright

Copy link
Copy Markdown
Owner

Closes #386, #387, #398, #399, #400, #401, #402, #403, #404.

Changes

Verification

kanon gate --full green; cargo test --workspace passes (23 binaries). akouo-android compiles + tests host-side (UniFFI scaffolding); Android NDK cross-compile is not exercised on this host.

Notes

Adds an OutputConfig.enabled flag (default true) so headless decode/analysis works without an audio device — a small design addition beyond the nine issues. The f64 DSP hot path allocation profile is unchanged.

…gnaling)

- #386: real Engine::seek via a watch channel to the decode task, awaiting
  the decoder's actual post-seek position (was a fabricated SeekCompleted).
- #387: the DSP ring-buffer emits EngineEvent::Error and stops instead of
  livelocking when a decoded frame exceeds ring capacity.
- #398: real Android seek (mirrors #386).
- #399: Android subscribe_events returns an id and gains an unsubscribe path
  so the listener list no longer grows unbounded.
- #400: notify() snapshots listener handles under the lock, then invokes the
  foreign callbacks after releasing it, so a reentrant subscribe/unsubscribe
  no longer deadlocks the non-reentrant std mutex.
- #401: PlaybackStarted is emitted before the decode/dsp tasks are spawned,
  so it can no longer be reordered after Error/TrackEnded.
- #402: the decode->DSP channel carries DecodeOutcome{Frame,Eos,Failed}, so a
  decode failure is distinct from end-of-stream and never emits TrackEnded.
- #403: all blocking decode/probe file I/O moves off the async executor into
  a dedicated blocking path (decode/blocking.rs).
- #404: cpal output-stream errors surface as EngineEvent::Error via an error
  channel instead of being only logged.

Closes #386
Closes #387
Closes #398
Closes #399
Closes #400
Closes #401
Closes #402
Closes #403
Closes #404

Gate-Passed: kanon 0.1.5 +stages:fmt,check,clippy,nextest,lint sha:af979dfe9cc18e05d2fd3cf11af3d3b3314cbd13
@forkwright
forkwright force-pushed the fix/akouo-playback-engine branch from bc2809b to abb3bfe Compare July 1, 2026 22:42
@forkwright
forkwright merged commit 8c027af into main Jul 1, 2026
11 checks passed
@forkwright
forkwright deleted the fix/akouo-playback-engine branch July 1, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Engine::seek is a stub that fabricates SeekCompleted and returns the requested position as the position reached

1 participant