Skip to content
Lin Cheng

I build, test, and examine things—and share what I learn.

Debugging Whole-House Bluetooth: What I Learned from OpenComm, Multipoint, and a Raspberry Pi

My open-ear headset kept dropping when I walked away from the Mac. After testing power classes, multipoint, and codecs, the fix was architectural: a Raspberry Pi as a remote Bluetooth endpoint on the home network.

I recently spent far too much time debugging what sounded like a simple problem: I wanted to wear an open-ear Bluetooth headset all day and stay connected while moving around the house.

My headset is the original AfterShokz OpenComm, model ASC100. I use it primarily for calls and voice interaction rather than music. The open-ear bone-conduction design matters because conventional headphones can become uncomfortable when worn for many hours, especially when they trap moisture around or inside the ear.

The OpenComm also supports Bluetooth multipoint, so I normally connect it to both my MacBook and my Android phone. When I am at my desk, this is almost ideal. Audio from either device can reach the headset without manually switching connections.

The problem started when I walked away from the Mac.

The original problem: Bluetooth range

My MacBook sits in one part of the house, while the bathroom is far enough away, with enough walls in between, that the OpenComm eventually loses its connection.

At first the symptoms were merely annoying. I would walk away, hear the headset announce that one device had disconnected, and continue using the phone.

The worse part happened if I stayed away for several minutes. When I returned, the Mac connection often would not recover automatically. I had to turn the headset off and on again.

Doing that several times a day rather defeats the point of wearing an always-available communication headset.

My first thought was obvious: could I use something equivalent to a Wi-Fi extender?

Unfortunately, normal Bluetooth headsets do not have an equivalent of Wi-Fi access points and roaming. There are Bluetooth gateways and mesh technologies for other applications, but there is no common consumer system where a headset seamlessly roams between multiple Bluetooth access points around a house.

That led to a more fundamental question: what actually determines Bluetooth range?

Class 1 versus Class 2 matters, but it is not the whole story

The original OpenComm is roughly a Class 2 device. Its FCC testing shows peak transmit power around 2.7 dBm, consistent with the traditional Class 2 range category.

Newer devices can transmit considerably more strongly. The OpenComm2, for example, is marketed for much longer range and operates in Class 1 territory.

My MacBook Pro is also capable of much higher Bluetooth transmit power than the original OpenComm.

Initially this made the diagnosis look simple: perhaps the headset was simply the weak side of the link.

But Bluetooth is bidirectional. The Mac must be able to reach the headset, and the headset must also be able to reach the Mac. Receiver sensitivity, antenna design, walls, interference, multipath propagation, and device placement all matter.

Then I ran a more useful experiment.

A Class 1 headset still struggled in the same location

I connected a Sennheiser Momentum 4 to the Mac and walked to the same troublesome part of the house.

The Momentum 4 has a stronger Bluetooth implementation than the original OpenComm.

It performed better initially. Instead of immediately losing the connection, the music became badly choppy.

But when I tested an actual bidirectional call, even the Momentum 4 eventually disconnected.

That was important.

It showed that replacing the OpenComm with a newer Class 1 headset might improve things, but it would not necessarily solve the real problem.

The house itself had a difficult RF path.

This was exactly the kind of problem Wi-Fi solves by changing geometry rather than merely increasing transmitter power.

So I decided to do the same thing for Bluetooth.

Turning a Raspberry Pi into a remote Bluetooth endpoint

I already had a Raspberry Pi 4B.

Instead of forcing the Mac to talk directly to the headset across the whole house, I paired the OpenComm with the Pi and placed the Pi somewhere more central.

The architecture became:

MacBook
   │
   │ Ethernet / Wi-Fi
   ▼
Raspberry Pi
   │
   │ Bluetooth
   ▼
OpenComm

The long-distance part now uses the home network, which already has good coverage.

Bluetooth is only responsible for the shorter final hop between the Pi and the headset.

This immediately makes much more architectural sense.

Wi-Fi is excellent at covering a building. Bluetooth is excellent for connecting nearby peripherals. Asking Bluetooth to do both jobs was the original mistake.

Getting two-way audio working

The Pi was running PipeWire and BlueZ.

The OpenComm exposes two relevant Bluetooth audio modes.

A2DP provides higher-quality playback but no microphone. HFP provides bidirectional audio and exposes the headset microphone.

The headset appeared as a normal PipeWire Bluetooth device. After switching to the HFP/mSBC profile, I got both:

OpenComm speaker ← Raspberry Pi

OpenComm microphone → Raspberry Pi

I recorded the boom microphone locally on the Pi and played the recording back. It worked.

That proved the Bluetooth side of the system.

The next step was transporting audio between the Mac and the Pi.

For the prototype I used raw PCM over UDP. This is deliberately unsophisticated, but it removes unnecessary codec complexity.

The Mac sent audio over the LAN to the Pi, and the Pi sent it to the headset.

The opposite direction worked too:

OpenComm mic
    ↓
Raspberry Pi
    ↓ UDP
MacBook

At this point the entire bidirectional architecture worked.

macOS virtual audio devices

To make ordinary Mac applications use the remote headset, I installed BlackHole virtual audio devices.

Conceptually, the final Mac-side path is:

Mac application
      ↓
virtual audio output
      ↓
network relay
      ↓
Raspberry Pi
      ↓
Bluetooth
      ↓
OpenComm

And for the microphone:

OpenComm
   ↓
Bluetooth
   ↓
Raspberry Pi
   ↓
network relay
   ↓
virtual microphone
   ↓
Mac application

This means applications do not need to know that the Bluetooth headset is physically attached to another computer.

The Pi effectively becomes a remote Bluetooth audio interface.

The unexpected discovery: multipoint was causing another problem

While investigating range, I discovered a second issue.

Even while sitting close to the Mac, the OpenComm would occasionally develop severe periodic stuttering.

The connection did not necessarily drop. Instead, audio would repeatedly pause or break every few seconds.

Restarting the headset fixed it.

Eventually I tried something more useful: while the stuttering was happening, I disconnected the phone.

The stuttering immediately disappeared.

That strongly suggested the problem was related to multipoint rather than RF range.

I repeated the experiment with the Raspberry Pi replacing the Mac as one of the two Bluetooth devices.

The same severe stuttering returned when the OpenComm maintained simultaneous connections to the Pi and the phone.

Then I disabled multipoint completely and used only one Bluetooth connection.

The severe periodic stuttering disappeared.

That was probably the most useful result of the entire investigation.

The original OpenComm’s multipoint implementation appears significantly less reliable than its single-device operation in my setup.

The Android phone by itself is extremely stable.

The Pi by itself is also much more stable.

The ugly recurring stutter appears when the headset tries to maintain two active Bluetooth relationships.

The Pi is not perfect either

The Raspberry Pi connection still produces an occasional small glitch.

This is different from the severe multipoint stuttering.

With multipoint enabled, the interruption is obvious and repetitive, like an audio pipeline repeatedly failing to keep up.

With only the Pi connected, I might hear one small interruption after several minutes.

Switching from HFP/mSBC to A2DP/SBC improved this further.

That makes sense. HFP is a lower-bandwidth bidirectional call profile and involves different timing and buffering behaviour.

I also tested disabling Wi-Fi on the Raspberry Pi to rule out obvious Wi-Fi/Bluetooth coexistence issues. It made no meaningful difference.

The remaining occasional glitch could therefore come from several places: PipeWire scheduling, BlueZ, the Pi’s onboard Bluetooth controller, buffering, clock drift, or the RF implementation itself.

But at this point I stopped treating that as the main problem.

The important result was much larger.

Moving the Bluetooth endpoint solved the whole-house coverage problem

With the Pi centrally located, I can walk around the house, including to the bathroom, while audio from the Mac continues playing.

The connection does not drop.

That is the problem I originally wanted to solve.

Instead of:

MacBook ───── multiple walls ───── OpenComm

I now effectively have:

MacBook
   │
   │ reliable home network
   ▼
central Raspberry Pi
   │
   │ short Bluetooth path
   ▼
OpenComm

The lesson is simple:

Bluetooth range is not only about transmitter power. Geometry can dominate everything.

Moving the radio endpoint by a few metres and removing difficult walls from the path can be more effective than buying a theoretically stronger headset.

This is exactly why Wi-Fi networks use multiple access points.

Bluetooth headsets simply do not have an equivalent consumer roaming architecture.

What about a USB Bluetooth dongle?

The Pi 4 uses an integrated Bluetooth/Wi-Fi radio. A separate USB Bluetooth adapter could potentially improve the remaining occasional glitches through a better antenna, different controller firmware, or better RF placement.

A more radical option would be a self-contained USB Bluetooth audio transmitter.

That would produce an architecture like:

Mac
 │
LAN
 │
Pi
 │ USB Audio
 │
Bluetooth transmitter
 │
OpenComm

In that design, the USB transmitter handles much of the Bluetooth implementation itself instead of relying on Linux BlueZ for the complete audio stack.

I may test this later.

But it is no longer necessary to prove the central idea.

The central idea already works.

What I learned

The investigation ended up revealing three largely independent issues:

  1. Range: the original Mac-to-headset path crosses too many walls. Moving the Bluetooth endpoint to a centrally located Raspberry Pi solves this.
  2. Multipoint: the original OpenComm becomes much less stable when simultaneously connected to two devices. Single-device operation is substantially better.
  3. Gateway implementation: the Raspberry Pi audio path has occasional minor glitches, probably somewhere in the Linux audio/Bluetooth stack or onboard radio, but it is dramatically less disruptive than the original range and multipoint problems.

There is also a broader design lesson here.

We normally think of a Bluetooth headset as being physically attached to the computer using it.

That assumption is unnecessary.

A better architecture for whole-house use is:

applications
    ↓
IP network
    ↓
Bluetooth gateway near the user
    ↓
headset

The gateway could be a Raspberry Pi, a dedicated appliance, or theoretically even functionality integrated into a Wi-Fi access point.

Once audio is transported over IP, Bluetooth only has to solve the problem it is actually good at: the last few metres.

And amusingly, after spending hours investigating power classes, codecs, dongles, FCC reports and Bluetooth profiles, the biggest improvement came from the oldest networking trick in the book:

put the radio in a better place.


Published

Next in TechnologyLLMs are too positive. Ask for the veto.
Subscribe via RSS
中