Skip to content

fix(audio): close the idle system-sound engine - #243

Merged
dianjixz merged 1 commit into
CardputerZero:masterfrom
guohui85:fix/system-sound-idle-close
Nov 13, 2026
Merged

dianjixz merged 1 commit into
CardputerZero:masterfrom
guohui85:fix/system-sound-idle-close

Conversation

@guohui85

@guohui85 guohui85 commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The system-sound engine (Cp0SystemSoundPlayer) never closes once it has played a sound, so a PulseAudio/PipeWire playback stream stays open for the whole session. While the device idles, the ES8389 codec, PipeWire and the launcher keep processing silence. This PR closes the engine after 10 s with nothing queued and nothing playing.

Why it stays open today

  • The first key click opens the engine, and nothing closes it again.
  • The lock screen was meant to close it: enter_lockscreen() calls suspend_system_sound() (→ close_engine()). But it then calls play_lockscreen_sound("lock.mp3") right away, which reopens the engine. So the stream runs for as long as the device sleeps.

Change

worker_loop() waits with a 10 s timeout while the engine is open. When it times out with no queued command and no sound playing (ma_sound_is_playing on every initialised sound), it calls close_engine(). The next sound reopens the engine through the existing path, with the existing 300 ms warm-up. Explicit Suspend / Prepare / Reload handling is unchanged.

Measurements

These were taken on a CardputerZero running launcher 0.6.105 with this patch applied (the file differs between 0.6.105 and master only by the removal of an unused kDefaultSoundCount constant). Conditions: screen locked, backlight off, no app running, on battery. I sampled current_now from bq27220 every 2 s for 60 s.

launcher current context switches ES8389 playback PCM
official 0.6.105 268 mA 4606 /s RUNNING
with this patch 217 mA 977 /s closed
with this patch (2nd run) 215 mA 716 /s closed

That is about 50 mA, roughly 19 % of the idle draw. The CPU also stopped sitting at 1 GHz while idle.

Testing

  • sh ext_components/cp0_lvgl/tests/run_tests.sh passes.
  • The existing test_audio_system_sound_player cannot exercise the idle close, because the engine never opens without an audio device and assets. I verified it on the device by checking /proc/asound/card1/pcm0p/sub0/status and wpctl status before and after.
  • Lock/unlock sounds, key clicks and Music playback still work. (After 10 s of silence, the first click reopens the engine and waits for the 300 ms warm-up.)

Note

I prepared this with AI assistance (Claude) and tested it on my own device. I'm happy to adjust the timeout or the approach.

- The system-sound engine stayed open after its first sound, keeping a
  PulseAudio/PipeWire playback stream running: the ES8389 codec, the
  sound server and the launcher kept processing silence while idle.
- The lock screen made it permanent: entering it suspends the engine and
  then plays lock.mp3, which reopens it for as long as the device sleeps.
- The worker now closes the engine after 10 s with no queued command and
  no sound playing; the next sound reopens it (with the existing 300 ms
  warm-up).
- Measured on a CardputerZero (0.6.105 + this change, screen locked, on
  battery): 268 mA -> 215/217 mA, context switches 4600/s -> ~800/s, and
  the ES8389 playback PCM goes from RUNNING to closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0135vUaG2FpgpGRJfB9LEPvZ
@dianjixz
dianjixz merged commit 4971015 into CardputerZero:master Nov 13, 2026
7 checks passed
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.

2 participants