Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

zephyr-cp: audiobusio.I2SOut.playing never becomes False after a non-looping sample finishes

オープン
#11,084 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
c
領域
embedded-iot

調査の方向性

Start in ports/zephyr-cp/common-hal/audiobusio/I2SOut.c, tracing fill_buffer(), the audio thread's exit, and common_hal_audiobusio_i2sout_get_playing(). Then investigate how Zephyr reports that I2S draining has completed and how thread/slab resources are safely released. Done means a non-looping sample finishes draining without its tail being dropped, playing becomes false, and resources can be used safely by a subsequent play().

索引モデルが issue の本文から書いたものです。

説明

audio bug zephyr

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.

Summary

On the zephyr-cp port, audiobusio.I2SOut has no end-of-playback detection. After a non-looping sample (loop=False) finishes, I2SOut.playing stays True indefinitely — it is only ever cleared by an explicit stop() (or a write error). So the common idiom

i2s.play(sample, loop=False)
while i2s.playing:
    pass

hangs forever.

Where

ports/zephyr-cp/common-hal/audiobusio/I2SOut.c

  • common_hal_audiobusio_i2sout_get_playing() simply returns self->playing.
  • self->playing is set False only in common_hal_audiobusio_i2sout_stop() and on an i2s_write error.
  • When a non-looping sample ends, fill_buffer() sets self->stopping = true and triggers I2S_TRIGGER_DRAIN; the audio thread then exits — but leaves self->playing == true.

Relationship to #10539

The single-buffer loop=False "no sound" bug (the final GET_BUFFER_DONE buffer being dropped before it was copied) was fixed for zephyr-cp as part of the #10539 work. This playing-never-clears problem is a separate, deeper gap and was deliberately scoped out, because a correct fix is non-trivial in the current design:

  • The audio thread cannot clean itself up (it can't k_thread_join/free from within itself, and setting playing = false there would break the next play(), which guards on playing).
  • Clearing it from get_playing() by calling stop() would issue I2S_TRIGGER_DROP, discarding the still-draining tail blocks (the DRAIN just triggered) and cutting off the end of the sample.
  • Doing it cleanly requires waiting until the I2S peripheral has actually finished draining (a driver-state query the code does not currently perform) before finalizing and freeing resources.

Suggested direction

Add drain-aware completion detection: once the sample is exhausted and the queued blocks have fully drained, clear playing and release the thread/slab resources — without dropping the tail. This likely needs a Zephyr I2S state query and/or coordination with the audio thread's exit.

Notes

  • Affects any non-looping sample on zephyr-cp, not just single-buffer RawSample; WaveFile with loop=False would exhibit the same stuck playing.
  • Other ports (espressif, nordic, raspberrypi, atmel-samd, ...) clear playing on completion; this gap is specific to zephyr-cp.
主要言語
C
スター
4.6k
フォーク
1.4k
平均マージ
1日 8時間
マージ済み PR(30日)
153

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

adafruit/circuitpython のほかの issue

adafruit/circuitpython の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。