Skip to content

feat(bt): Add HFP HCI Audio example sketches#12462

Merged
me-no-dev merged 13 commits into
espressif:masterfrom
MarcFinns:feature/hfp-hci-audio-example
Apr 11, 2026
Merged

feat(bt): Add HFP HCI Audio example sketches#12462
me-no-dev merged 13 commits into
espressif:masterfrom
MarcFinns:feature/hfp-hci-audio-example

Conversation

@MarcFinns
Copy link
Copy Markdown
Contributor

@MarcFinns MarcFinns commented Mar 18, 2026

By completing this PR sufficiently, you help us to review this Pull Request quicker and also help improve the quality of Release Notes

Checklist

  1. Please provide specific title of the PR describing the change, including the component name (eg. „Update of Documentation link on Readme.md")
  2. Please provide related links (eg. Issue which will be closed by this Pull Request)
  3. Please update relevant Documentation if applicable
  4. Please check Contributing guide
  5. Please confirm option to "Allow edits and access to secrets by maintainers" when opening a Pull Request

Description of Change

Adds two example sketches demonstrating bidirectional SCO audio over HCI using the ESP32 HFP client profile.

HFP_HCI_Audio — Simple example, no external hardware required.
Includes a compile-time switch (AUDIO_MODE) between two modes:

  • AUDIO_MODE_TONE — generates a 1 kHz sine wave and sends it to the phone (TX path test)
  • AUDIO_MODE_LOOPBACK — echoes incoming audio back to the caller (full duplex test)

The sketch uses a FreeRTOS StreamBuffer as a ring buffer to decouple the audio producer from the Bluedroid BTA consumer, absorbing scheduling jitter. Both CVSD (8 kHz) and mSBC (16 kHz) codecs are supported transparently.

HFP_HCI_Audio_I2S — Fully functional I2S audio bridge for real hardware.
Routes SCO audio between a paired phone and external audio hardware:

  • Phone → ESP32 → PCM5102A DAC (I2S playback)
  • PCM1808 ADC → ESP32 → Phone (I2S capture)

The I2S peripheral is reconfigured automatically to match the negotiated codec (CVSD 8 kHz or mSBC 16 kHz). Tested on ESP32 with an iPhone using both codecs.

Test Scenarios

Tested on ESP32 with Arduino-esp32 core using a custom build of the precompiled libraries (see Related links) with an iPhone as the paired phone. Both AUDIO_MODE_TONE and AUDIO_MODE_LOOPBACK verified working on CVSD and mSBC codecs. The I2S bridge verified working with PCM5102A + PCM1808 on both CVSD and mSBC.

Related links

Depends on: espressif/esp32-arduino-lib-builder#360 (merged) — enables CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI and CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI in the precompiled libraries.

@MarcFinns MarcFinns requested a review from a team as a code owner March 18, 2026 22:44
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


MarcFinns seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 18, 2026

Warnings
⚠️

Some issues found for the commit messages in this PR:

  • the commit message "Update README with build requirements clarification":
    • body's lines must not be longer than 100 characters
    • summary looks empty
    • type/action looks empty

Please fix these commit messages - here are some basic tips:

  • follow Conventional Commits style
  • correct format of commit message should be: <type/action>(<scope/component>): <summary>, for example fix(esp32): Fixed startup timeout issue
  • allowed types are: change,ci,docs,feat,fix,refactor,remove,revert,test
  • sufficiently descriptive message summary should be between 10 to 72 characters and start with upper case letter
  • avoid Jira references in commit messages (unavailable/irrelevant for our customers)

TIP: Install pre-commit hooks and run this check when committing (uses the Conventional Precommit Linter).

Messages
📖 This PR seems to be quite large (total lines of code: 1736), you might consider splitting it into smaller PRs

👋 Hello MarcFinns, we appreciate your contribution to this project!


📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more.

🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project.

Click to see more instructions ...


This automated output is generated by the PR linter DangerJS, which checks if your Pull Request meets the project's requirements and helps you fix potential issues.

DangerJS is triggered with each push event to a Pull Request and modify the contents of this comment.

Please consider the following:
- Danger mainly focuses on the PR structure and formatting and can't understand the meaning behind your code or changes.
- Danger is not a substitute for human code reviews; it's still important to request a code review from your colleagues.
- Resolve all warnings (⚠️ ) before requesting a review from human reviewers - they will appreciate it.
- Addressing info messages (📖) is strongly recommended; they're less critical but valuable.
- To manually retry these Danger checks, please navigate to the Actions tab and re-run last Danger workflow.

Review and merge process you can expect ...


We do welcome contributions in the form of bug reports, feature requests and pull requests.

1. An internal issue has been created for the PR, we assign it to the relevant engineer.
2. They review the PR and either approve it or ask you for changes or clarifications.
3. Once the GitHub PR is approved we do the final review, collect approvals from core owners and make sure all the automated tests are passing.
- At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation.
4. If the change is approved and passes the tests it is merged into the default branch.

Generated by 🚫 dangerJS against 7b93d16

@MarcFinns MarcFinns force-pushed the feature/hfp-hci-audio-example branch from 5bc4cea to a67b9a3 Compare March 18, 2026 23:28
@lucasssvaz
Copy link
Copy Markdown
Member

If you need to add custom sdkconfig options, isn't it better to make this example an Arduino as component example ?

@MarcFinns
Copy link
Copy Markdown
Contributor Author

MarcFinns commented Mar 19, 2026

If you need to add custom sdkconfig options, isn't it better to make this example an Arduino as component example ?

You don't need custom sdk options, there is a matching pull request already accepted. There was an inconsistency, so that an arduino sketch could control the flow of a telephone call, but could not handle the audio. This is now fixed.
This is just an example on how to use it. I was asked to provide it!

@MarcFinns
Copy link
Copy Markdown
Contributor Author

@CLAassistant recheck - I’ve signed the CLA!

@me-no-dev
Copy link
Copy Markdown
Member

CLA is a pita sometimes. No worries. I'll merge the libs with your changes and then pull them here for the CI to pass

@me-no-dev
Copy link
Copy Markdown
Member

Would be nice to have the example also use our I2S lib to pass Audio. That would be a realistic example. Also if any buttons are supported, adding those would be nice too.

@MarcFinns
Copy link
Copy Markdown
Contributor Author

Would be nice to have the example also use our I2S lib to pass Audio. That would be a realistic example. Also if any buttons are supported, adding those would be nice too.

Indeed that is how i plan to use the feature, but I have not built the hardware yet! (before wasting time, i wanted to make sure that the software part would be feasible). When done I'll be glad to provide a working example.

@me-no-dev
Copy link
Copy Markdown
Member

You should not need a hardware. The library is pretty basic. Important is to show where and how much to read and write and what should be sample rate, etc.

@me-no-dev me-no-dev requested a review from lucasssvaz as a code owner March 19, 2026 10:03
@me-no-dev
Copy link
Copy Markdown
Member

I will also suggest to make the comments in the code readable by people who are not intimate with HFP/HCI

@MarcFinns
Copy link
Copy Markdown
Contributor Author

@me-no-dev Points taken, as soon as i have a minute i will look into it. thanks for your feedback

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 19, 2026

Memory usage test (comparing PR against master branch)

The table below shows the summary of memory usage change (decrease - increase) in bytes and percentage for each target.

MemoryFLASH [bytes]FLASH [%]RAM [bytes]RAM [%]
TargetDECINCDECINCDECINCDECINC
ESP32000.000.00000.000.00
Click to expand the detailed deltas report [usage change in BYTES]
TargetESP32
ExampleFLASHRAM
libraries/ESP32/examples/HFP_HCI_Audio--
libraries/ESP32/examples/HFP_HCI_Audio_I2S--

@lucasssvaz
Copy link
Copy Markdown
Member

Please make sure that the format specifiers follow the rules described in this table:

https://docs.espressif.com/projects/arduino-esp32/en/latest/guides/coding_guidelines.html#format-specifiers

@MarcFinns
Copy link
Copy Markdown
Contributor Author

You should not need a hardware. The library is pretty basic. Important is to show where and how much to read and write and what should be sample rate, etc.

Hi @me-no-dev I connected PCM5102A (I2S DAC) and PCM1808 (I2S ADC) Aliexpress breakout boards and a button.
With the button I can pick up / hangout a call, and audio of the phone call nicely flows from the adc and dac.
Is this of interest? if so, shall i replace the test sketch or add it?
Please let me know, this is my first contribution! thanks

@me-no-dev
Copy link
Copy Markdown
Member

@MarcFinns yes please. Example that runs on actual hardware is always better to have

@MarcFinns
Copy link
Copy Markdown
Contributor Author

@MarcFinns yes please. Example that runs on actual hardware is always better to have

Replacing the previous example or adding a new one, then?

@me-no-dev
Copy link
Copy Markdown
Member

replace or make it optional in the example

@MarcFinns
Copy link
Copy Markdown
Contributor Author

@MarcFinns yes please. Example that runs on actual hardware is always better to have

@me-no-dev As discussed, I added the example that run on real I2S hardware to the PR #12462
Not sure how to specify that it requires the PR in the lib builder (espressif/esp32-arduino-lib-builder#360 (merged) — enables CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI and CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI in the precompiled libraries)

@MarcFinns MarcFinns changed the title Add HFP HCI Audio example sketch feat(bt): Add HFP HCI Audio example sketches Mar 24, 2026
@me-no-dev me-no-dev requested a review from Copilot March 25, 2026 12:17
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/ESP32_HFP_HCI_Audio_I2S.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/ESP32_HFP_HCI_Audio_I2S.ino Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds two new Arduino-ESP32 Bluetooth Classic HFP example sketches demonstrating bidirectional SCO audio over HCI, including a minimal “no hardware” loopback/tone generator and a full I2S audio bridge example for external ADC/DAC hardware.

Changes:

  • Added HFP_HCI_Audio example sketch with TONE/LOOPBACK modes using an esp_timer + FreeRTOS buffer to drive HFP SCO TX/RX over HCI.
  • Added HFP_HCI_Audio_I2S example sketch bridging SCO audio to external I2S hardware (PCM5102A/PCM1808) with automatic codec rate reconfiguration.
  • Added README + CI metadata for the new examples.

Reviewed changes

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

File Description
libraries/ESP32/examples/HFP_HCI_Audio_I2S/README.md Documents wiring/usage/build requirements for the I2S SCO↔I2S bridge example.
libraries/ESP32/examples/HFP_HCI_Audio_I2S/ESP32_HFP_HCI_Audio_I2S.ino Implements the HFP client + SCO-over-HCI audio path bridged to I2S RX/TX with an ADC capture task and StreamBuffer.
libraries/ESP32/examples/HFP_HCI_Audio/ci.yml Adds CI constraints and required sdkconfig flags for the HFP_HCI_Audio example build.
libraries/ESP32/examples/HFP_HCI_Audio/HFP_HCI_Audio.ino Implements the minimal HFP SCO-over-HCI example with loopback/tone modes and periodic pull triggering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/README.md
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/README.md
Comment thread libraries/ESP32/examples/HFP_HCI_Audio/ci.yml
Comment thread libraries/ESP32/examples/HFP_HCI_Audio/HFP_HCI_Audio.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio/HFP_HCI_Audio.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio/HFP_HCI_Audio.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio/HFP_HCI_Audio.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/ESP32_HFP_HCI_Audio_I2S.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/ESP32_HFP_HCI_Audio_I2S.ino Outdated
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/HFP_HCI_Audio_I2S.ino Outdated
@MarcFinns MarcFinns force-pushed the feature/hfp-hci-audio-example branch from 72db4f6 to f448a76 Compare March 25, 2026 22:05
MarcFinns and others added 4 commits March 28, 2026 15:34
Comment thread libraries/ESP32/examples/HFP_HCI_Audio_I2S/HFP_HCI_Audio_I2S.ino
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lucasssvaz lucasssvaz added the Status: Pending CLA ⚠️ Contributor is required to sign the CLA label Apr 6, 2026
@me-no-dev
Copy link
Copy Markdown
Member

@MarcFinns please sign CLA

@MarcFinns
Copy link
Copy Markdown
Contributor Author

MarcFinns commented Apr 8, 2026

@MarcFinns please sign CLA

@me-no-dev I did, multiple times. I have 2 email addresses in my profile and i did it with both. It appears signed!
Tried again, for the Nth time

@lucasssvaz lucasssvaz added Status: Pending Merge Pull Request is ready to be merged and removed Status: Pending CLA ⚠️ Contributor is required to sign the CLA labels Apr 8, 2026
@me-no-dev
Copy link
Copy Markdown
Member

@github-actions github-actions Bot added the Status: Pre-commit fixes required ⚠️ The pre-commit bot can't fix the issues automatically. Please fix the issues manually. label Apr 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

⚠️ Pre-commit Hooks Failed

Some pre-commit hooks failed and require manual fixes. Please see the detailed error report below.

What to do:

  1. 📋 View the detailed error report to see which hooks failed
  2. 🔧 Fix the issues locally in your code
  3. 💾 Commit and push your changes
  4. 🔄 The hooks will run again automatically

Need help? Ask in the comments below.

Replace British spellings (initialise/initialisation/behaviour/
minimising/recognisable) with American English equivalents required
by the project's codespell pre-commit hook.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MarcFinns
Copy link
Copy Markdown
Contributor Author

@MarcFinns some syntax errors left to be fixed: https://github.com/espressif/arduino-esp32/actions/runs/24189514220/job/70602927776?pr=12462#step:8:29

@me-no-dev Ahahaha, is this a joke? this side of the pond we use British English..!

@lucasssvaz
Copy link
Copy Markdown
Member

@MarcFinns some syntax errors left to be fixed: https://github.com/espressif/arduino-esp32/actions/runs/24189514220/job/70602927776?pr=12462#step:8:29

@me-no-dev Ahahaha, is this a joke? this side of the pond we use British English..!

American English is the official spelling used by Espressif:

https://mos.espressif.com/general-conventions.html#american-or-british-spelling

@github-actions github-actions Bot removed the Status: Pre-commit fixes required ⚠️ The pre-commit bot can't fix the issues automatically. Please fix the issues manually. label Apr 9, 2026
…tions

Remove backslash line continuations from // comments inside #define
macros — these cause -Werror=comment compilation failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@me-no-dev me-no-dev merged commit e756fce into espressif:master Apr 11, 2026
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Pending Merge Pull Request is ready to be merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants