Skip to content

Enable working HFP Voice-over-HCI software audio on Classic-Bluetooth ESP32 targets #12450

@MarcFinns

Description

@MarcFinns

Related area

Bluetooth Classic / HFP

Hardware specification

ESP32 (original dual-mode ESP32 variants with Classic Bluetooth support)

Is your feature request related to a problem?

Yes. Arduino ESP32 currently exposes HFP client APIs that strongly suggest software call audio should be possible, but the packaged Bluetooth library does not provide a usable software audio path.

Today, an Arduino sketch can:

  • start Classic Bluetooth
  • pair with a phone
  • establish HFP service-level connection
  • answer a call
  • establish SCO audio

But once SCO audio is connected, the sketch still cannot actually send or receive call audio in software in a usable way.

In practice, the current build is in an awkward middle state:

  • the public headers expose HFP software-audio APIs
  • the packaged libbt.a exports HFP control-plane functions
  • but the actual software PCM path is incomplete or nonfunctional in the Arduino-distributed build

This creates a frustrating developer experience: the feature appears to exist, the connection state reaches CONNECTED_CVSD, yet no software audio data is delivered to the sketch.

Describe the solution you'd like

Ship Arduino ESP32 with a complete, working HFP Voice-over-HCI software-audio path for Classic-Bluetooth-capable ESP32 targets, or explicitly document that the exposed HFP software-audio APIs are unsupported in Arduino builds.

The preferred outcome is full support.

What this should mean in practice:

  • if a sketch uses esp_bredr_sco_datapath_set(ESP_SCO_DATA_PATH_HCI), software HFP audio should work
  • if HFP client headers expose software-audio APIs, the packaged BT library should export and support them
  • outgoing microphone PCM should be writable from software
  • incoming call audio PCM should be readable from software
  • existing Bluetooth sketches that do not use HFP audio should remain unaffected

At minimum, the existing low-level ESP-IDF-style APIs should work reliably from Arduino on supported targets:

#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_hf_client_api.h"

void hf_event_cb(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param) {
  if (event == ESP_HF_CLIENT_AUDIO_STATE_EVT) {
    // Should reach CONNECTED_CVSD / CONNECTED_MSBC
  }
}

uint32_t outgoing_audio_cb(uint8_t *buf, uint32_t len) {
  memset(buf, 0, len);  // or generate a tone / send PCM
  return len;
}

void incoming_audio_cb(const uint8_t *buf, uint32_t len) {
  // Process incoming call audio in software
}

void setup() {
  esp_hf_client_register_callback(hf_event_cb);
  esp_hf_client_init();
  esp_bredr_sco_datapath_set(ESP_SCO_DATA_PATH_HCI);
  esp_hf_client_register_data_callback(incoming_audio_cb, outgoing_audio_cb);
}

If the newer Voice-over-HCI push API is intended to be public, that should also be available in the packaged Arduino BT library:

#include "esp_hf_client_api.h"

void hf_audio_rx_cb(esp_hf_sync_conn_hdl_t sync_conn_hdl,
                    esp_hf_audio_buff_t *audio_buf,
                    bool is_bad_frame) {
  esp_hf_client_audio_buff_free(audio_buf);
}

void setup() {
  esp_hf_client_register_audio_data_callback(hf_audio_rx_cb);
}

Key features

  • working HFP client software audio over HCI on Classic-Bluetooth ESP32 targets
  • matching public headers and packaged BT library capabilities
  • software access to outgoing microphone audio
  • software access to incoming call audio
  • narrowband CVSD support at 8 kHz
  • optional mSBC support where available
  • no impact on boards without Classic Bluetooth

Describe alternatives you've considered

ESP-IDF directly

This is the only realistic path today if a project needs software-accessible HFP audio, but it defeats the purpose of using Arduino ESP32 and pushes users out of the Arduino ecosystem entirely.

At the moment, the only practical way to get working HFP software audio is to abandon Arduino for a native ESP-IDF workflow or maintain a custom core/toolchain build.

Custom Arduino core / custom BT library build

Possible in theory, but not reasonable for most users. It turns a simple prototype into a fork-maintenance problem.

Using the currently exposed legacy callback API as-is

This is what I tried. HFP control works, SCO connects, but no outgoing audio callback is ever invoked during an active call.

Relying on external codec hardware instead

That changes the project entirely. The goal here is software-accessible HFP audio over HCI, not an external hardware workaround.

Additional context

Why this request is reasonable

This does not look like a request for a brand-new subsystem. Most of the plumbing is already present:

  • HFP client control APIs are already exposed
  • SCO audio setup already works
  • the headers already advertise software-audio support
  • the packaged library already contains HFP client code

The missing piece appears to be packaging completeness and support alignment, not a fundamentally new architecture.

Native HFP software audio in Arduino would unlock:

  • telephony gateways
  • POTS / analog phone experiments
  • call-tone and signaling generators
  • custom DSP on live call audio
  • accessibility, automotive, and intercom prototypes

This is one of those features that makes the ESP32 feel dramatically more capable, because it turns a phone call into something the sketch can actually interact with, not just control from a distance.

Observed behavior in Arduino ESP32

In my tests on Arduino ESP32 3.3.7:

  • HFP pairing works
  • HFP SLC connection works
  • incoming call answer works
  • SCO audio reaches CONNECTED_CVSD
  • but the outgoing software audio callback never fires

I also verified that the headers expose more HFP software-audio APIs than the packaged libbt.a actually exports, which suggests a mismatch between the public API surface and the distributed Bluetooth library build.

Suggested scope

If needed, this could be limited to:

  • original ESP32 targets only
  • Classic-Bluetooth-capable boards only
  • existing Bluedroid-based builds only

That should keep the feature low-risk and avoid affecting BLE-only targets.

Community interest
Software-accessible HFP audio would unlock an entire class of Bluetooth telephony projects in Arduino ESP32 that are currently blocked at the final step. The control plane is already there. The audio plane is the missing half.

I have checked existing list of Feature requests and the Contribution Guide

  • I confirm I have checked existing list of Feature requests and Contribution Guide.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions