Skip to content

feat(bsp): microphone record/playback and tabbed example UIs for audio-capable boards#674

Merged
finger563 merged 17 commits into
mainfrom
feat/bsp-audio-examples
Jul 23, 2026
Merged

feat(bsp): microphone record/playback and tabbed example UIs for audio-capable boards#674
finger563 merged 17 commits into
mainfrom
feat/bsp-audio-examples

Conversation

@finger563

Copy link
Copy Markdown
Contributor

Description

Give the BSP components that have audio input a consistent way to exercise recording, playback, and volume control, and reorganize their examples into a multi-page UI so the widgets are no longer crammed onto one screen.

Example UI (esp-box, t-deck, m5stack-tab5, esp32-p4-function-ev-board, smartpanlee-sc01-plus):

  • Reorganize each example into a tabbed (lv_tabview) UI so the IMU drawing, audio controls, and other widgets each get their own page. Drawing is confined to its own page, so swiping between tabs no longer smears points onto the other pages.
  • Wrapping tab labels (still readable when the display is rotated) and speaker icons on the volume buttons.

Microphone support:

  • esp-box, t-deck, m5stack-tab5: on-screen record/playback GUI and a microphone-volume API, reading the ES7210 ADC.
  • esp32-p4-function-ev-board: record/playback GUI reading the ES8311 ADC.
  • m5stack-cardputer: microphone-volume API and function-key volume controls.
  • play_audio is now streaming-friendly (append what fits, report how many bytes were queued) so callers can stream buffers larger than the speaker stream buffer, and playback keeps that buffer topped up to avoid underrun static. On-screen volume labels stay in sync with the live BSP state.

m5stack-tab5 (full-duplex ES8388 + ES7210) audio:

  • Fix the RX channel to share the TX standard-mode clock, enable the ES7210 high-pass filter, and drain RX from a dedicated microphone task (blocking read) rather than the shared playback task. On this single full-duplex controller an irregularly-drained RX ring perturbs the TX and both degrades the recording and pops the playback; the dedicated task mirrors the well-behaved esp-box path and yields clean capture.
  • The example applies DC removal and an RMS-normalized software makeup gain to each recording, so it plays back at an audible level from a low analog mic gain (the ES7210 front-end whines when the analog gain is driven hard).

T-Deck ES7210 microphone (needed the most work):

  • Read the ES7210 as its fixed 4-slot TDM frame and keep the two populated microphones (MIC1 / MIC3); a narrower read misframes the codec.
  • Enable the ES7210 digital high-pass filter so the mic DC offset stops railing the ADC, and let the driver derive bclk_div so MCLK matches the codec coefficient table (a forced divider was slipping frames).
  • Run the example at 16 kHz so playback pitch is correct, and make the trackball center button optional (GPIO0 conflicts with the mic).
  • The mic is genuinely low-sensitivity and picks up random electrical impulse noise, so the example post-processes each recording: de-glitch (mark and interpolate), DC removal, and an RMS-normalized software makeup gain. This is the practical limit of the board's microphone hardware, documented in the example README.

Example configuration (kept out of the BSP defaults):

  • Raise the LVGL task stacks, and on esp-box / t-deck the interrupt/touch task stack, through each example's sdkconfig.defaults so existing users of the components are unaffected; enable the end-of-stack watchpoint on those two boards and PSRAM where the recording buffers need it. All documented in the example READMEs.
  • Lower the m5stack-tab5 I/O-expander init log verbosity (INFO -> WARN).

Motivation and Context

Allows users to exercise the microphone and speaker on all BSP boards that have them, and gives a consistent UI and API for doing so.

The T-Deck microphone is low-sensitivity and noisy, so the example post-processes the recording to make it audible.

How has this been tested?

Build and run the examples on the esp-box, t-deck, m5stack-tab5, esp32-p4-function-ev-board, and m5stack-cardputer. The examples exercise the microphone and speaker, and the volume controls are verified to work.

Screenshots (if appropriate, e.g. schematic, board, console logs, lab pictures):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update
  • Hardware (schematic, board, system design) change
  • Software change

Checklist:

  • My change requires a change to the documentation.
  • I have added / updated the documentation related to this change via either README or WIKI

Software

  • I have added tests to cover my changes.
  • I have updated the .github/workflows/build.yml file to add my new test to the automated cloud build github action.
  • All new and existing tests passed.
  • My code follows the code style of this project.

…o-capable boards

Give the BSP components that have audio input a consistent way to exercise
recording, playback, and volume control, and reorganize their examples into a
multi-page UI so the widgets are no longer crammed onto one screen.

Example UI (esp-box, t-deck, m5stack-tab5, esp32-p4-function-ev-board,
smartpanlee-sc01-plus):
- Reorganize each example into a tabbed (lv_tabview) UI so the IMU drawing,
  audio controls, and other widgets each get their own page. Drawing is
  confined to its own page, so swiping between tabs no longer smears points
  onto the other pages.
- Wrapping tab labels (still readable when the display is rotated) and speaker
  icons on the volume buttons.

Microphone support:
- esp-box, t-deck, m5stack-tab5: on-screen record/playback GUI and a
  microphone-volume API, reading the ES7210 ADC.
- esp32-p4-function-ev-board: record/playback GUI reading the ES8311 ADC.
- m5stack-cardputer: microphone-volume API and function-key volume controls.
- play_audio is now streaming-friendly (append what fits, report how many
  bytes were queued) so callers can stream buffers larger than the speaker
  stream buffer, and playback keeps that buffer topped up to avoid underrun
  static. On-screen volume labels stay in sync with the live BSP state.

m5stack-tab5 (full-duplex ES8388 + ES7210) audio:
- Fix the RX channel to share the TX standard-mode clock, enable the ES7210
  high-pass filter, and drain RX from a dedicated microphone task (blocking
  read) rather than the shared playback task. On this single full-duplex
  controller an irregularly-drained RX ring perturbs the TX and both degrades
  the recording and pops the playback; the dedicated task mirrors the
  well-behaved esp-box path and yields clean capture.
- The example applies DC removal and an RMS-normalized software makeup gain to
  each recording, so it plays back at an audible level from a low analog mic
  gain (the ES7210 front-end whines when the analog gain is driven hard).

T-Deck ES7210 microphone (needed the most work):
- Read the ES7210 as its fixed 4-slot TDM frame and keep the two populated
  microphones (MIC1 / MIC3); a narrower read misframes the codec.
- Enable the ES7210 digital high-pass filter so the mic DC offset stops
  railing the ADC, and let the driver derive bclk_div so MCLK matches the
  codec coefficient table (a forced divider was slipping frames).
- Run the example at 16 kHz so playback pitch is correct, and make the
  trackball center button optional (GPIO0 conflicts with the mic).
- The mic is genuinely low-sensitivity and picks up random electrical impulse
  noise, so the example post-processes each recording: de-glitch (mark and
  interpolate), DC removal, and an RMS-normalized software makeup gain. This
  is the practical limit of the board's microphone hardware, documented in the
  example README.

Example configuration (kept out of the BSP defaults):
- Raise the LVGL task stacks, and on esp-box / t-deck the interrupt/touch task
  stack, through each example's sdkconfig.defaults so existing users of the
  components are unaffected; enable the end-of-stack watchpoint on those two
  boards and PSRAM where the recording buffers need it. All documented in the
  example READMEs.
- Lower the m5stack-tab5 I/O-expander init log verbosity (INFO -> WARN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 19:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR adds consistent microphone record/playback and volume control capabilities across audio-capable BSPs, and reorganizes several board examples into tabbed LVGL UIs to avoid overcrowding and drawing artifacts.

Changes:

  • Add microphone initialization/capture APIs (ES7210/ES8311) and example record/playback flows.
  • Make play_audio() streaming-friendly by returning the number of bytes actually queued.
  • Rework multiple example GUIs into lv_tabview pages and adjust example sdkconfig.defaults for stack/PSRAM needs.

Reviewed changes

Copilot reviewed 48 out of 48 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
components/t-deck/src/t-deck.cpp Make trackball center button optional to avoid GPIO0 mic conflicts
components/t-deck/src/audio.cpp Add ES7210 mic capture path; make play_audio return queued bytes
components/t-deck/include/t-deck.hpp Expose mic API + play_audio() return value and trackball option
components/t-deck/example/sdkconfig.defaults Enable PSRAM and increase task stacks for the example
components/t-deck/example/main/t_deck_example.cpp Add record/playback UI wiring + 16 kHz fixed-rate pipeline
components/t-deck/example/main/gui.hpp Convert example UI to tabview + add audio widgets/callbacks
components/t-deck/example/main/gui.cpp Implement tabbed Draw/Audio UI and live volume/status labels
components/t-deck/example/README.md Document stack/PSRAM config and T-Deck mic quality limitations
components/t-deck/README.md Document dual-mic recording support via ES7210
components/t-deck/CMakeLists.txt Add codec dependency for ES7210 usage
components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp Make play_audio() return queued byte count
components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp Document new play_audio() return semantics
components/smartpanlee-sc01-plus/example/sdkconfig.defaults Increase interrupt stack for touch error logging
components/smartpanlee-sc01-plus/example/main/smartpanlee_sc01_plus_example.cpp Route drawing to Draw tab; add Audio-tab play callback
components/smartpanlee-sc01-plus/example/main/gui.hpp Tabview UI + audio controls callback plumbing
components/smartpanlee-sc01-plus/example/main/gui.cpp Implement tabview + audio controls and label updates
components/smartpanlee-sc01-plus/example/README.md Document example audio controls + stack override rationale
components/m5stack-tab5/src/m5stack-tab5.cpp Reduce IO expander init log verbosity
components/m5stack-tab5/src/audio.cpp Fix full-duplex RX config; add mic HPF + mic task + streaming play_audio
components/m5stack-tab5/include/m5stack-tab5.hpp Update audio API return values + add mic volume API
components/m5stack-tab5/example/sdkconfig.defaults Increase interrupt stack size for touch error logging
components/m5stack-tab5/example/main/m5stack_tab5_example.cpp Add record/playback + post-processing + tabbed UI usage
components/m5stack-tab5/example/main/gui.hpp Convert to tabview and add Audio tab controls/callbacks
components/m5stack-tab5/example/main/gui.cpp Implement Draw/Status/Audio tabs and volume/status widgets
components/m5stack-tab5/example/README.md Document recording/playback UI and stack override rationale
components/m5stack-cardputer/src/microphone.cpp Add mic volume control (ES8311 hw or PDM software scaling)
components/m5stack-cardputer/src/m5stack-cardputer.cpp Apply stored mic volume during ES8311 mic init
components/m5stack-cardputer/include/m5stack-cardputer.hpp Expose microphone_volume() API and docs
components/m5stack-cardputer/example/main/m5stack_cardputer_example.cpp Add function-key speaker/mic volume shortcuts
components/m5stack-cardputer/example/main/gui.hpp Update help text with new volume shortcuts
components/m5stack-cardputer/example/README.md Document new keybindings for speaker/mic volume
components/m5stack-cardputer/README.md Document mic volume behavior across variants
components/esp32-p4-function-ev-board/src/audio.cpp Add ES8311 ADC mic capture task + streaming-friendly playback
components/esp32-p4-function-ev-board/include/esp32-p4-function-ev-board.hpp Expose mic API + play_audio() return values
components/esp32-p4-function-ev-board/example/sdkconfig.defaults Increase interrupt/touch stacks for touch error logging
components/esp32-p4-function-ev-board/example/main/gui.hpp Convert example UI to tabview + add Audio controls
components/esp32-p4-function-ev-board/example/main/gui.cpp Implement Status/Audio tabs and record/play/volume widgets
components/esp32-p4-function-ev-board/example/main/esp32_p4_function_ev_board_example.cpp Add record/playback buffer + tab-limited drawing
components/esp32-p4-function-ev-board/example/README.md Document recording UI and stack overrides
components/esp32-p4-function-ev-board/README.md Document full-duplex ES8311 playback + recording API
components/esp-box/src/audio.cpp Add ES7210 mic support + clamp volume + return queued bytes
components/esp-box/include/esp-box.hpp Expose mic API + streaming-friendly play_audio() signature
components/esp-box/example/sdkconfig.defaults Enable PSRAM + stack watchpoint + increase interrupt stack
components/esp-box/example/main/gui.hpp Convert example UI to tabview + add Audio controls/callbacks
components/esp-box/example/main/gui.cpp Implement Draw/IMU/Audio tabs and live volume/status labels
components/esp-box/example/main/esp_box_example.cpp Add mic record/playback buffering + tab-limited drawing
components/esp-box/example/README.md Document audio recording/playback UI behavior and stack overrides
components/esp-box/README.md Document full-duplex audio and mic recording pipeline
Comments suppressed due to low confidence (1)

components/t-deck/src/audio.cpp:1

  • xStreamBufferSendFromISR() is intended for ISR context; calling it from normal task context is undefined/not portable across FreeRTOS ports. Consider switching to xStreamBufferSend(..., 0) for non-blocking task calls, or implement a small helper that uses xPortInIsrContext() to choose between xStreamBufferSend() and xStreamBufferSendFromISR().

Comment thread components/m5stack-tab5/include/m5stack-tab5.hpp
Comment thread components/m5stack-tab5/src/audio.cpp Outdated
Comment thread components/esp-box/example/main/gui.cpp
Comment thread components/esp-box/src/audio.cpp
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

✅Static analysis result - no issues found! ✅

Copilot AI review requested due to automatic review settings July 22, 2026 21:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 49 changed files in this pull request and generated 8 comments.

Comment thread components/esp-box/src/audio.cpp
Comment thread components/t-deck/src/audio.cpp
Comment thread components/m5stack-tab5/src/audio.cpp
Comment thread components/esp32-p4-function-ev-board/src/audio.cpp
Comment thread components/t-deck/src/audio.cpp
Comment thread components/esp-box/src/audio.cpp
Comment thread components/m5stack-tab5/src/audio.cpp
Comment thread components/m5stack-cardputer/src/microphone.cpp
Copilot AI review requested due to automatic review settings July 23, 2026 00:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 49 changed files in this pull request and generated 3 comments.

Comment thread components/t-deck/src/audio.cpp
Comment thread components/esp-box/src/audio.cpp
Comment thread components/m5stack-tab5/src/audio.cpp Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 01:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 49 changed files in this pull request and generated 8 comments.

Comments suppressed due to low confidence (1)

components/esp-box/src/audio.cpp:237

  • play_audio() can enqueue a byte count that is not aligned to 16-bit stereo frames (4 bytes). If a caller streams an odd/non-frame-aligned size, the stream buffer can end up with partial samples, which will shift audio framing and may leave 1–3 bytes that the audio task never drains cleanly.
  // don't block here: append what fits into the stream buffer and report how
  // much was actually queued so callers can stream data larger than the buffer.
  // This runs in task context, so use the non-ISR send with a 0 timeout (never
  // blocks) rather than the FromISR variant.
  return xStreamBufferSend(audio_tx_stream, data, num_bytes, 0);

Comment thread components/t-deck/src/audio.cpp
Comment thread components/m5stack-tab5/src/audio.cpp Outdated
Comment thread components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp
Comment thread components/esp32-p4-function-ev-board/src/audio.cpp Outdated
Comment thread components/t-deck/example/main/t_deck_example.cpp Outdated
Comment thread components/esp-box/example/main/esp_box_example.cpp Outdated
Comment thread components/m5stack-tab5/example/main/m5stack_tab5_example.cpp Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 02:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 9 comments.

Comment thread components/t-deck/include/t-deck.hpp
Comment thread components/t-deck/src/audio.cpp Outdated
Comment thread components/t-deck/example/main/t_deck_example.cpp
Comment thread components/t-deck/src/audio.cpp Outdated
Comment thread components/esp-box/src/audio.cpp Outdated
Comment thread components/m5stack-tab5/src/audio.cpp Outdated
Comment thread components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp Outdated
Comment thread components/m5stack-cardputer/src/audio.cpp Outdated
Comment thread components/esp32-p4-function-ev-board/src/audio.cpp Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 02:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings July 23, 2026 03:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 5 comments.

Comment thread components/t-deck/example/main/t_deck_example.cpp Outdated
Comment thread components/smartpanlee-sc01-plus/example/main/gui.cpp
Comment thread components/t-deck/src/audio.cpp Outdated
Comment thread components/esp-box/src/audio.cpp Outdated
Comment thread components/m5stack-tab5/src/audio.cpp Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 03:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (3)

components/t-deck/include/t-deck.hpp:1

  • The PR description (and checkbox) indicates a “non-breaking change”, but changing play_audio(...) from void to size_t is an API-breaking change for downstream callers (compile-time break). Consider keeping the old void overloads as wrappers (possibly marked deprecated) that forward to the new size_t versions, or introduce a new method name (e.g., enqueue_audio(...)) while keeping the existing signature stable.
    components/t-deck/src/audio.cpp:1
  • If es7210_adc_config_i2s(...) fails, the code logs but continues as if the microphone is configured. This can leave the capture pipeline in a misconfigured state while still enabling the RX channel and starting the task. Consider treating this as a hard failure: return false and perform the same cleanup path used for other init failures (disable/delete I2S channel, reset handles, etc.).
    components/t-deck/src/audio.cpp:1
  • A single std::error_code hpf_ec is reused across four register writes; depending on how write_register updates hpf_ec on success, this can (a) report only the last failing write, or (b) keep a stale error value and warn even if a later write succeeds. Consider resetting/checking the error code per write (or logging which register failed) so HPF configuration failures are diagnosable and the warning reflects the actual failure.

Comment thread components/esp-box/src/audio.cpp
Comment thread components/esp32-p4-function-ev-board/src/audio.cpp Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 14:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 2 comments.

Comment thread components/m5stack-tab5/src/audio.cpp Outdated
Comment thread components/smartpanlee-sc01-plus/example/main/gui.cpp
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 23, 2026 16:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 4 comments.

Comment thread components/t-deck/src/audio.cpp Outdated
Comment thread components/esp-box/src/audio.cpp Outdated
Comment thread components/esp32-p4-function-ev-board/src/audio.cpp Outdated
Comment thread components/smartpanlee-sc01-plus/example/main/gui.cpp Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 23, 2026 16:59
finger563 and others added 2 commits July 23, 2026 12:00
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (6)

components/t-deck/example/main/t_deck_example.cpp:1

  • The microphone callback writes into recording_buffer concurrently with the main loop, and the main loop begins post-processing the same buffer immediately when it observes recording transition to false. Because an in-flight callback invocation may have already passed its if (!recording) return; check, this can create a data race (concurrent memcpy vs post-processing reads/writes), which is undefined behavior in C++. A concrete fix is to add a synchronization point when stopping recording (e.g., stop/suspend the microphone delivery before processing, or use a mutex/sequence counter so the main loop waits until no callback is active before touching recording_buffer).
    components/m5stack-tab5/src/audio.cpp:1
  • On either task start failure path, the function returns false but leaves previously-initialized audio resources (I2S channels enabled, codec started/configured, stream buffers allocated) in a partially-initialized state. This can cause resource leaks and unpredictable behavior if the caller retries initialization or continues using the object. Consider adding explicit teardown/rollback here (disable/del I2S channels, stop codec ADC/DAC as appropriate, release buffers) so failure is cleanly recoverable.
    components/t-deck/src/audio.cpp:1
  • initialize_microphone() returns bool and already uses error-return patterns, but it also uses ESP_ERROR_CHECK(...) for multiple calls; those will hard-abort the program on failure instead of returning false with cleanup/logging. For consistency and better robustness (especially on boards where peripherals may be absent/miswired), prefer checking the return codes and performing the same cleanup paths you already have (disable/del channel, null handles, etc.) rather than aborting.
    components/t-deck/src/audio.cpp:1
  • initialize_microphone() returns bool and already uses error-return patterns, but it also uses ESP_ERROR_CHECK(...) for multiple calls; those will hard-abort the program on failure instead of returning false with cleanup/logging. For consistency and better robustness (especially on boards where peripherals may be absent/miswired), prefer checking the return codes and performing the same cleanup paths you already have (disable/del channel, null handles, etc.) rather than aborting.
    components/t-deck/src/audio.cpp:1
  • initialize_microphone() returns bool and already uses error-return patterns, but it also uses ESP_ERROR_CHECK(...) for multiple calls; those will hard-abort the program on failure instead of returning false with cleanup/logging. For consistency and better robustness (especially on boards where peripherals may be absent/miswired), prefer checking the return codes and performing the same cleanup paths you already have (disable/del channel, null handles, etc.) rather than aborting.
    components/smartpanlee-sc01-plus/example/main/gui.cpp:1
  • last_volume / last_muted are static function locals, so they’re shared across all Gui instances and survive across deinit/reinit cycles; they also differ from the member-variable approach used in the other GUIs in this PR. Prefer making these cached values instance members (like last_speaker_volume_ / last_mic_volume_ elsewhere) so state is correctly scoped and reset with the Gui object lifecycle.

Comment thread components/esp-box/include/esp-box.hpp
Copilot AI review requested due to automatic review settings July 23, 2026 17:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (3)

components/t-deck/src/audio.cpp:1

  • play_audio() now unconditionally uses xStreamBufferSend() (task API) whereas the previous implementation used xStreamBufferSendFromISR(). If any existing caller invokes play_audio() from ISR context (or from an IDF callback that can run in ISR context), this can trigger FreeRTOS asserts or undefined behavior at runtime. Consider making this robust by branching on ISR context (e.g., xPortInIsrContext()): use xStreamBufferSendFromISR() when in ISR and xStreamBufferSend() otherwise, while still enforcing frame alignment, or add a dedicated ISR-safe play_audio_from_isr() API if ISR use is intended.
    components/t-deck/src/audio.cpp:1
  • audio_rx_buffer is a std::vector<uint8_t>, so audio_rx_buffer.data() is only byte-aligned by the C++ standard; reinterpreting and dereferencing it as int16_t* is undefined behavior due to potential misalignment (even if it often “works” on some targets). A concrete fix is to store the RX buffer as std::vector<int16_t> (or another explicitly aligned allocation), perform compaction in that typed buffer, and pass reinterpret_cast<const uint8_t*>(samples) to the callback with a byte length.
    components/smartpanlee-sc01-plus/example/main/gui.cpp:1
  • last_volume / last_muted are static function locals, which makes the cache shared across all Gui instances and persist across deinit/reinit. This can cause the label to stop updating in scenarios like recreating the GUI (or having multiple GUIs in tests). Store these as Gui member fields (similar to the last_speaker_volume_ / last_mic_volume_ pattern used in the other tabbed UIs) so caching is instance-scoped.

Comment thread components/esp-box/include/esp-box.hpp
Comment thread components/esp32-p4-function-ev-board/src/audio.cpp
Copilot AI review requested due to automatic review settings July 23, 2026 18:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

components/t-deck/src/audio.cpp:1

  • The default branch silently maps unsupported rate values to AUDIO_HAL_16K_SAMPLES without also forcing the I2S clock (sample_rate_hz) to 16 kHz. That creates a codec coefficient-table mismatch (the exact issue this PR is trying to avoid) if a caller passes an unsupported rate. Prefer making unsupported rates a hard error (return false / log) or normalize the actual configured sample rate (use the fallback rate consistently for both I2S and codec).
    components/t-deck/src/audio.cpp:1
  • This change makes play_audio() explicitly task-context only (uses xStreamBufferSend). Previously, the implementation used xStreamBufferSendFromISR, which likely made some downstream code assume ISR-safety. If ISR callers exist, they will now fail at runtime. To keep the API robust, consider supporting both contexts (e.g., detect ISR context and route to xStreamBufferSendFromISR with frame-aligned sizing), or provide a dedicated play_audio_from_isr(...) entry point while preserving the current task-only contract.

Comment thread components/esp32-p4-function-ev-board/src/audio.cpp
Comment thread components/esp-box/src/audio.cpp
@finger563
finger563 merged commit 5bfa5ee into main Jul 23, 2026
131 checks passed
@finger563
finger563 deleted the feat/bsp-audio-examples branch July 23, 2026 19:31
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