Troubleshooting Glitchy Bluetooth Audio on Windows

Hi, when outputting through my Sony WH-1000XM4 bluetooth headphones on Windows, realtime audio from the server sounds glitchy, with incorrect transients, clicks, pauses, and “fast forward” pitch increases. These artifacts are seemingly not tied to the signal itself, they occur at random times even when replaying the same signal.

Here is a pathological synthdef that always exhibits the behavior for me, though it can also occur randomly during normal usage.

var def = SynthDef.new(\pulse, { arg out, amp, freq, degree, gate = 1, dur;
	var feedback = LocalIn.ar(2);

	var fuzz = 0.05;
	var attackTime = 0.04;
	var osc = [
		SinOsc.ar((60 + degree + 12).midicps, phase: fuzz * feedback[0].range(0, 2pi)),
		SinOsc.ar((60 + degree + 24).midicps, phase: fuzz * feedback[1].range(0, 2pi))
	] * EnvGen.ar(Env.asr(
		attackTime: (attackTime) * dur,
		releaseTime: (1 - attackTime) * dur
	), gate: gate);

	LocalOut.ar(osc);
	Out.ar(out, amp * Mix.ar(osc));
}).add;

server.sync;

Pmono(def.name, *[
	degree: Pseries(0, 1, 8)
]).play;

I tried the following troubleshooting steps.

i) I verified it is caused by outputting via bluetooth. Listening to the above on same machine with the same settings through the same headphones but using a real wire, no bluetooth, the audio sounds fine. This is also the case for the system speakers

ii) I recorded the above to .wav with the same settings as the server, then played back that recording using PlayBuf using the server. Listening to this on the bluetooth headphones, no artifacting occurred. Listening to this .wav in other apps including audacity and the default windows media player, no artifacting occurrs either. It only happens for audio synthesized in realtime by the supercollider server.

iii) I disabled all Windows “audio enhancement”, including “Windows Sonic” and “Dolby Atmos”. This did not fix the issue.

iv) On startup, the server prints:

Booting with:
  In: Windows WASAPI : Mikrofonarray (Intel® Smart Sound Technologie für digitale Mikrofone)
  Out: Windows WASAPI : Kopfhörer (WH-1000XM4)
  Sample rate: 48000.000
  Latency (in/out): 0.022 / 0.023 sec
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 256

The server sample rate matches that of my device, though trying other common sample rates made no difference to the artifacting.

v) ServerOptions.devices.do{|x| x.postln}; prints the following, where I omitted some of the irrelevant entries such as mics:

MME : Microsoft Sound Mapper - Input
MME : Mikrofonarray (Intel® Smart Sou
MME : Kopfhörer (WH-1000XM4)
MME : Microsoft Sound Mapper - Output
MME : Kopfhörer (WH-1000XM4)
MME : Lautsprecher (Senary Audio)
Windows DirectSound : Primary Sound Capture Driver
Windows DirectSound : Kopfhörer (WH-1000XM4)
Windows DirectSound : Primary Sound Driver
Windows DirectSound : Kopfhörer (WH-1000XM4)
Windows DirectSound : Lautsprecher (Senary Audio)
Windows WASAPI : Kopfhörer (WH-1000XM4)
Windows WASAPI : Lautsprecher (Senary Audio)
Windows WASAPI : Kopfhörer (WH-1000XM4)
Windows WDM-KS : Kopfhörer ()
Windows WDM-KS : Output 1 (Senary Audio headphone)
Windows WDM-KS : Output 2 (Senary Audio headphone)
Windows WDM-KS : Input (Senary Audio headphone)
Windows WDM-KS : Output 1 (Senary Audio output)
Windows WDM-KS : Output 2 (Senary Audio output)
Windows WDM-KS : Input (Senary Audio output)
Windows WDM-KS : Kopfhörer (@System32\drivers\bthhfenum.sys,#2;%1 Hands-Free%0

;(WH-1000XM4))
Windows WDM-KS : Kopfhörer (@System32\drivers\bthhfenum.sys,#2;%1 Hands-Free%0

The blank lines and duplicate entries were what was printed to the console, I did not copy it incorrectly.

I tried every device related to my headphones. only Windows WASAPI : Kopfhörer (WH-1000XM4) (the default) had good audio quality, DirectSound, WDM-KS and MME sounded like a cheap headsets but they did not exhibit the audio glitching.


I feel like it could be a latency issue but I don’t know which server option to set to what, or what other steps to take to trouble shoot. Windows does not allow you to change the bluetooth codec to my knowledge, and I couldn’t find any settings outside of supercollider that influenced playback.

Thank you for any suggestions.

First, I haven’t tried Bluetooth with SC in Windows, so I’m speculating. But…

A 256-sample hardware buffer is for lower-latency cases such as live processing of mic input onstage.

Bluetooth cannot do low latency, period.

This, I’ve seen directly (using Pipewire in Linux). Over the summer, I did a lecture-demo back in the States. I didn’t want to carry bulky pro headphones, so I practiced the set on my Bluetooth earpieces. The set did involve mic input, so I had mic → USB soundcard → SC → Bluetooth. If I clicked my tongue near the mic, the output through the earpieces followed, oh, 100-200 ms later. So Pipewire was running at “256 samples” but it added extra latency for the output device’s requirements.

100-200 ms would line up to a hardware buffer size of 4096 or 8192 samples. This matches with my experience trying to run the JACK server through bluez-alsa in the pre-Pipewire days – it would simply not work at all below 8192 samples (and even then, I’d get only 15 minutes before JACK would crash and require a reboot).

So the first thing I’d try in your case is a much larger buffer size. I’m not sure in Windows if this needs to be configured in an OS settings panel, or if the SC ServerOptions hardwareBufferSize setting will do it.

Beyond that I’ve no idea…

hjh

thank you, I do not particularly care about latency, I’m fine with the signal coming even a second later than it is synthesized, as long as the signal itself is free of errors and glitches, as I don’t often use both my headphones and mic / midi-in.

Maybe someone knows how to configure SC to give the OS more time before sending the samples via bluetooth

A quick web search for “Windows how to configure Bluetooth audio driver settings” turned up an AI slop article with some perhaps useful information:

https://windowsforum.com/news/mastering-bluetooth-settings-in-windows-10-11-a-complete-guide.352876/

Summary for Windows 11:​ Right-click Start → Settings → Bluetooth & devices → Devices → More Bluetooth settings.

Summary for Windows 10: Right-click Start → Settings → Devices → Bluetooth & other devices → More Bluetooth options.

I’m not on Windows though, so I can’t confirm what’s in those dialogs beyond what’s in the article.

You could also try s.options.hardwareBufferSize = 8192 before booting the server. I’m not 100% sure that will work – as I understand it, this option requests a buffer size from the audio driver, but the driver might override that…? It’s a bit murky, but easy to try.

hjh