You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Android: sound crackles through Bluetooth headsets #308
On Android, sound through Bluetooth earbuds crackles constantly: short bursts of sound with gaps of silence between them. The same app plays cleanly on the phone's speaker. I'm working on a music player and a mobile game and ran in to this problem on both apps.
Together with Claude we figured out the cause, the fix works for both apps.
The cause is the read size in internal/oboe/binding_android.cpp. LoopRead reads getBufferSizeInFrames() * 3 frames from Go at once. On a Pixel 8 Pro with Sony WF-1000XM4 earbuds, the AAudio stream reports:
so each read asks the players for 55,350 frames, about 1.15 seconds. In mux.ReadFloat32s, a player hands over only what it has buffered, and the rest of the read stays silent. Our app keeps 20 to 150 ms buffered, so most of each read was silence. The default player buffer is 0.5 s, so the same is likely for an app that keeps the default, though we tested only with our own.
The fifo and read_frames_ are also sized once, from the first stream, and kept when the sound moves to another device. The speaker reports burst=96 bufferSize=192.
Reproduction
Play sound through oto on an Android phone with Bluetooth earbuds connected (the two apps built on gunim, which plays through oto).
Listen: it crackles throughout.
Disconnect the earbuds: on the speaker it plays cleanly.
Expected behavior
The sound plays as cleanly on Bluetooth earbuds as on the speaker.
Possible Solution
#306 caps each read from Go at 10 ms, makes the fifo a second long once, and sets how full it is kept from the stream playing, as each stream opens.
Activity
internal/mux: pace the Android driver's reads, so players refill betw…
internal/mux: pace the Android driver's reads, so players refill betw…
internal/oboe: move the read pacing into the driver
internal/oboe: test the pacer from the external test package
internal/oboe: run the pacing test in virtual time
internal/oboe: keep a whole burst queued after any callback
internal/oboe: fix crackling on Bluetooth headsets (ebitengine#306)