Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Double-buffer RawSample (single_buffer=False) played with loop=False hangs; playing never clears

未关闭
#11,086 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
25/100
Issue 类型
缺陷
描述清晰度
需要澄清
活跃度
冷清
技术栈
c
领域
embedded-iot

调研方向

Start by reading the RawSample documentation and shared-module/audiocore/RawSample.c, then trace the rp2 behavior in ports/raspberrypi/audio_dma.c. Reproduce the hang and check the listed audio ports. Done means the intended double-buffer plus loop=False semantics are decided and implemented, with behavior verified across ports.

由索引模型根据 Issue 内容生成。

描述

audio bug

Note: This issue was written by Claude (via Claude Code), not by a human. It was filed at the request of @dhalbert while working on the fixes for #10539 (PR #11085).

@dhalbert says: This is kind of an edge case; no one has reported it as a bug; I discovered it while testing audio PR's.

Summary

A RawSample constructed with single_buffer=False and played with loop=False plays a short burst and then hangs: audio stops, but .playing never becomes False. Observed on raspberrypi; likely affects other ports (needs verification — see below).

sample = audiocore.RawSample(sine_wave, sample_rate=8000, single_buffer=False)
i2s.play(sample, loop=False)
while i2s.playing:   # never exits
    pass

Root cause (raspberrypi)

A double-buffer RawSample's get_buffer (shared-module/audiocore/RawSample.c) returns half the buffer with GET_BUFFER_DONE and alternates halves forever — it never signals true end-of-data.

On rp2 (ports/raspberrypi/audio_dma.c), audio_dma_load_next_block treats GET_BUFFER_DONE && !loop by pointing the DMA channel's chain at itself to stop. With both channels chained to themselves, the ping-pong breaks: channel[0] plays its half and stops, and dma_callback_fun never re-triggers (channels_to_load_mask == 0, filled_count == 1). Audio halts after one half, and playing_in_progress is never cleared. The proper end-of-sample detection (output_length_used == 0) never fires because RawSample always returns nonzero halves.

WaveFile in double-buffer mode is unaffected: it returns GET_BUFFER_MORE_DATA for intermediate reads and a truly-empty GET_BUFFER_DONE at EOF, so playback terminates cleanly.

Why this is tricky (semantics)

Per the RawSample docstring, single_buffer=False (double-buffered) is intended for continuous, live-update playback — updating the buffer while it plays — and its examples all use loop=True. single_buffer=False + loop=False on a static buffer is effectively ill-defined: the sample has no natural end, so "play once and stop" has no clear meaning.

A fix probably needs a decision at the RawSample/shared layer about what this combination should do (e.g. play the whole buffer through once then stop, treat it as looping, or reject the combination), rather than a per-port patch.

TODO

  • Reproduce on other audio ports (espressif, nordic, atmel-samd, mimxrt10xx, stm, zephyr-cp) and note behavior per port.
  • Decide the intended semantics for double-buffer + loop=False.
  • Implement, likely at the RawSample/shared-module layer.

Context

Discovered while fixing the single-buffer loop=False "no sound" / stuck-playing bugs in #10539 (PR #11085). This double-buffer case was deliberately scoped out of that PR.

主要语言
C
星标
4.6k
派生
1.4k
平均合并
1 天 8 小时
30 天内合并 PR
155

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

adafruit/circuitpython 的其他 Issue

查看 adafruit/circuitpython 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。