Bluetooth speakers problem between "paplay" and "ALSA"

My environment is OpenWrt 22.03.2 running on MediaTek MT7620A

I can't remember which packages were installed, but they all come from the following URL, and there are no third-party packages.

https://openwrt.org/docs/guide-user/hardware/bluetooth/bluetooth.audio
https://openwrt.org/docs/guide-user/hardware/bluetooth/bluetooth.speakers

paplay is working good, and I can hear it on the speaker.

root@OpenWrt:~# paplay -v test.wav
Opening a playback stream with sample specification 's16le 1ch 22050Hz' and channel map 'mono'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, tlength=88200, prebuf=87320, minreq=882
Using sample spec 's16le 1ch 22050Hz', channel map 'mono'.
Connected to device bluez_sink.AA_BB_CC_DD_EE_FF.a2dp_sink (index: 1, suspended: no).
Stream started.
Playback stream drained.: 54194 usec.          
Draining connection to server.

but aplay not, looks like ALSA can't find the card it needs.

root@OpenWrt:~# aplay test.wav 
ALSA lib confmisc.c:855:(parse_card) cannot find card '0'
ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_card_inum returned error: No such file or directory
ALSA lib confmisc.c:422:(snd_func_concat) error evaluating strings
ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1334:(snd_func_refer) error evaluating name
ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5701:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM default
aplay: main:831: audio open error: No such file or directory

How can I let ALSA find that card? I know it exists.

root@OpenWrt:~# pactl list cards
Card #0
	Name: bluez_card.AA_BB_CC_DD_EE_FF
	Driver: module-bluez5-device.c
	Owner Module: 12
	Properties:
		device.description = "A-02"
		device.string = "AA:BB:CC:DD:EE:FF"
		device.api = "bluez"
		device.class = "sound"
		device.bus = "bluetooth"
		device.form_factor = "hands-free"
		bluez.path = "/org/bluez/hci0/dev_AA_BB_CC_DD_EE_FF"
		bluez.class = "0x240408"
		bluez.alias = "A-02"
		device.icon_name = "audio-handsfree-bluetooth"
		device.intended_roles = "phone"
	Profiles:
		a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)
		off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
	Active Profile: a2dp_sink
	Ports:
		handsfree-output: Handsfree (type: Handsfree, priority: 0, latency offset: 0 usec, availability unknown)
			Part of profile(s): a2dp_sink
		handsfree-input: Handsfree (type: Handsfree, priority: 0, latency offset: 0 usec, not available)

BlueTooth speakers are too different from normal sound cards, and are therefore not exposed by the kernel as ALSA cards. There is simply no such driver, and it would be impossible to write one, as they don't use a circular buffer to which raw PCM audio samples are written directly. Existence of such a buffer is baked into the kernel ALSA API too deeply, and raw uncompressed PCM samples are not actually sent over BlueTooth - audio is always compressed.

Instead of the ALSA card, there is a BlueTooth adapter, which is a completely different type of a device from the kernel perspective, and PulseAudio deals with them separately (without using ALSA). There are two ways to make it work with ALSA:

  1. Configure ALSA to send audio to PulseAudio which would then send it to BlueTooth. To do that, you need the alsa-plugins package, which is not available on OpenWrt. On "normal" distributions, this provides the ALSA plugin pulse, which teaches ALSA applications to talk to PulseAudio (without using the notion of a card), and a file (something like /etc/alsa/conf.d/99-pulseaudio-default.conf) that activates this support by default for applications that don't specify their playback device at all.

  2. Skip PulseAudio, use the bluez-alsa package, which is, again, not available on OpenWRT. A pull request exists, so you may be able to bring it up to date and build the package from source.

So yeah, you can't do this officially, and OpenWrt is broken in this regard.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.