[Bluetooth-audio] How to connect and use Bluetooth headphones on FreeBSD

Summary:
With FreeBSD release 15 running on my Thinkpad T490, virtual_oss runs, my bluetooth headphones announce that they are connected, but no audio is played through my bluetooth headphones.

Details:
virtual_oss_bluetooth package is installed.
cuse kernel module loads successfully at startup.
hcsecd and sdpd services are configured to autostart at startup and they run successfully.
Bluetooth address of my Q32 headphones is configured in /etc/bluetooth/hosts

At startup, following messages (relevant to ubt0) appear in /var/log/messages
Code:
root@t490-bsd:~ # cat /var/log/messages | grep ubt0
Jan  8 02:59:13 t490-bsd kernel: ubt0 on uhub1
Jan  8 02:59:13 t490-bsd kernel: ubt0: <vendor 0x8087 product 0x0aaa, class 224/1, rev 2.00/0.02, addr 4> on usbus0
Jan  8 14:55:10 t490-bsd kernel: ubt0 on uhub0
Jan  8 14:55:10 t490-bsd kernel: ubt0: <vendor 0x8087 product 0x0aaa, class 224/1, rev 2.00/0.02, addr 4> on usbus0

Then, I turn my bluetooth headphones ON and run following commands as root.
Code:
root@t490-bsd:~ # service bluetooth stop ubt0
root@t490-bsd:~ # service bluetooth start ubt0
root@t490-bsd:~ # hccontrol -n ubt0hci create_connection Q32
root@t490-bsd:~ # hccontrol -n ubt0hci write_authentication_enable 1
root@t490-bsd:~ # virtual_oss -C 2 -c 2 -r 48000 -b 16 -s 1024 -R /dev/null -P /dev/bluetooth/Q32 -d dsp &
hw.snd.basename_clone: 0 -> 0
backend_bt: PSM=0x19

After running the virtual_oss command, my headphones announce that they are connected. But playing anything (from mplayer or firefox) results in no audio playing through my bluetooth headphones. It's worth noting that audio playback works just fine through the built-in speakers and wired headphones, without performing any of the steps above. Also, the same bluetooth headphones work fine with several other devices.

It's worth noting the following.
Code:
root@t490-bsd:~ # service bluetooth start ubt0
root@t490-bsd:~ # cat /var/log/messages | grep ubt0
Jan  8 02:59:13 t490-bsd kernel: ubt0 on uhub1
Jan  8 02:59:13 t490-bsd kernel: ubt0: <vendor 0x8087 product 0x0aaa, class 224/1, rev 2.00/0.02, addr 4> on usbus0
Jan  8 14:55:10 t490-bsd kernel: ubt0 on uhub0
Jan  8 14:55:10 t490-bsd kernel: ubt0: <vendor 0x8087 product 0x0aaa, class 224/1, rev 2.00/0.02, addr 4> on usbus0
Jan  8 15:00:53 t490-bsd kernel: ng_hci_process_command_timeout: ubt0hci - unable to complete HCI command OGF=0x3, OCF=0x3. Timeout

I am not sure what am I missing here. I have tried these and several other suggestions I have found all over the forums, but in vain.
I hope someone in this thread will be able to help me out. Thank you!
 
Option -d is meant to create a device, but dsp is an existing name. Try dsp9 instead, see if /dev/dsp9 is indeed created and configure your music player to use /dev/dsp9.
Thank you for pointing it out. I went back and confirmed there wasn't an existing /dev/dsp prior to creating the virtual_oss device. But just to be sure that the device name is unique, and following your suggestion, I modified the name of the new device created by virtual_oss to dsp_Q32. (terminal log is pasted at the bottom of this reply)

Following this, the headphones announce that they are connected, but unlike the past (where sound didn't play through the bluetooth headphones or the built in speakers), this time, audio played through the built in speakers, not the headphones. There is no sign of my new dis_Q32 device within mixertui and I don't know how to ensure that audio is channelled through the new device or even control the channel audio levels for the new device.

It is clear that my understanding of the FreeBSD audio subsystem is lacking. I haven't been able to figure out based on the audio subsystem information available in the handbook or the architecture handbook. It will be nice if someone could point me to an appropriate resource. Thank you!

Here is my latest terminal log.
Code:
root@t490-bsd:~ # ls /dev/dsp*
/dev/dsp0  /dev/dsp1  /dev/dsp2
root@t490-bsd:~ # cat /dev/sndstat
Installed devices:
pcm0: <Realtek ALC257 (Analog 2.0+HP/2.0)> (play/rec) default
pcm1: <Realtek ALC257 (Right Analog Mic)> (rec)
pcm2: <Intel Kaby Lake (HDMI/DP 8ch)> (play)
No devices installed from userspace.
root@t490-bsd:~ # service bluetooth stop ubt0
root@t490-bsd:~ # service bluetooth start ubt0
/etc/rc.d/bluetooth: WARNING: Reset failed, retrying.
root@t490-bsd:~ #
root@t490-bsd:~ # hccontrol -n ubt0hci create_connection Q32
BD_ADDR: Q32
Connection handle: 256
Encryption mode: Disabled [0]
root@t490-bsd:~ # hccontrol -n ubt0hci write_authentication_enable 1
root@t490-bsd:~ # virtual_oss -C 2 -c 2 -r 48000 -b 16 -s 1024 -R /dev/null -P /dev/bluetooth/Q32 -d dsp_Q32 &
root@t490-bsd:~ # backend_bt: PSM=0x19
root@t490-bsd:~ # ls /dev/dsp*
/dev/dsp0  /dev/dsp1  /dev/dsp2  /dev/dsp_Q32
root@t490-bsd:~ # cat /dev/sndstat
Installed devices:
pcm0: <Realtek ALC257 (Analog 2.0+HP/2.0)> (play/rec) default
pcm1: <Realtek ALC257 (Right Analog Mic)> (rec)
pcm2: <Intel Kaby Lake (HDMI/DP 8ch)> (play)
Installed devices from userspace:
dsp_Q32: <virtual_oss device> (play/rec)
 
This works for me:

virtual_oss -B -S -C 2 -c 2 -r 44100 -b 16 -s 1024 -R /dev/null -P /dev/bluetooth/thename -d dsp -t vdsp.ctl

[It works for me. I'm listening music through it right now (change "thename" though).]
 
this time, audio played through the built in speakers, not the headphones
Which probably means that your music player is sending its output to the default device, which is 'dsp'. Your output of cat /dev/sndstat shows your default device is pcm0. However, AlfredoLlaquet shows it is possible to use -d dsp. In your case that should give you the same output.
Now you can set your default device to your headphones. Alternatively, configure your music player to send its output to /dev/dsp_q32 or even directly to /dev/bluetooth/Q32. On a command line using mpv it would look something like this: mpv --audio-device=oss//dev/dsp_q32 song-to-play.mp3.
 
Which probably means that your music player is sending its output to the default device, which is 'dsp'. Your output of cat /dev/sndstat shows your default device is pcm0. However, AlfredoLlaquet shows it is possible to use -d dsp. In your case that should give you the same output.
Now you can set your default device to your headphones. Alternatively, configure your music player to send its output to /dev/dsp_q32 or even directly to /dev/bluetooth/Q32. On a command line using mpv it would look something like this: mpv --audio-device=oss//dev/dsp_q32 song-to-play.mp3.
Success! Here is my working setup script (to be run as root). Q32 is the name of my bluetooth headphones.

Code:
service bluetooth stop ubt0
service bluetooth start ubt0
hccontrol -n ubt0hci create_connection Q32
hccontrol -n ubt0hci write_authentication_enable 1
virtual_oss -B -S -C 2 -c 2 -r 44100 -b 16 -s 1024 -R /dev/null -P /dev/bluetooth/Q32 -d dsp_Q32 -t vdsp_Q32.ctl

After running this, my bluetooth headphones announce that they are connected.
Although, the new dsp_Q32 device is still not the systemwide default. Hence, all audio application still play through the laptop speakers.

To play audio through my bluetooth headphones, application needs to be specifically instructed to do so. I use following mplayer command on my laptop
Code:
mplayer -ao oss:/dev/dsp_Q32 <some_audio_file.mp3>
This now plays through only my bluetooth headphones, as expected.

Now, off to figure out how to do the following.
Edit: firefox uses the libcubeb to perform all the audio tasks. Based on https://dev1galaxy.org/viewtopic.php?id=7483, I was hoping that just setting media.cubeb.output_device in firefox about:config to /dev/dsp_Q32 would be sufficient. Unfortunately, it was not.

Then, looking at https://github.com/mozilla/cubeb/blob/975a727e5e308a04cfb9ecdf7ddaf1150ea3f733/src/cubeb_oss.c#L56, it is clear that libcubeb does not read any config parameters to determine the OSS audio output device, but rather reads the AUDIO_DEVICE environment variable, and if it is not set, it defaults to /dev/dsp. So, the solution for me was to start firefox as as follows
Code:
$ AUDIO_DEVICE=/dev/dsp_Q32 firefox
Now, I have audio from firefox playing only into my bluetooth headphones, which is what I was trying to achieve!

Thank you to everyone who helped me get this far!
 
Back
Top