bluez-alsa
bluez-alsa copied to clipboard
How to pipe bluealsa PCM to fifo?
I've been able to install, configure and start bluez-alsa on my headless server. I can see my BT devices and BT PCMs with bluealsa-aplay -L
and bluealsa-aplay -l
but when I try to pipe an output to /tmp/snapfifo (snapcast) I do not hear anything, why it could be?
aplay -D bluealsa:DEV=RA:ND:OM:MA:CA:DD,PROFILE=a2dp < /tmp/snapfifo
PS: I can successfully use the same pipe with mopidy
Shouldn't that <
be a >
?
Please can you clarify (I am not familiar with snapcast): are you trying to send audio from a phone to play it through snapcast, or are you trying to use snapcast to play audio from a file to a bluetooth speaker?
thank you for joining me @graham8 @borine, I'm sorry for missing this infos:
- I'm trying to use my phone as a source to play audio on a snapcast server
- snapcast can source audio from fifo and from alsa too.
- the bluetooth adapter is connected to the server
aplay -l
**** List of PLAYBACK Hardware Devices ****
aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
lavrate
Rate Converter Plugin Using Libav/FFmpeg Library
samplerate
Rate Converter Plugin Using Samplerate Library
speexrate
Rate Converter Plugin Using Speex Resampler
jack
JACK Audio Connection Kit
oss
Open Sound System
pulse
PulseAudio Sound Server
speex
Plugin using Speex DSP (resample, agc, denoise, echo, dereverb)
upmix
Plugin for channel upmix (4,6,8)
vdownmix
Plugin for channel downmix (stereo) with a simple spacialization
front:CARD=Intel
Front output / input
surround21:CARD=Intel
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Intel
4.0 Surround output to Front and Rear speakers
surround41:CARD=Intel
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Intel
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Intel
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Intel
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
usbstream:CARD=Intel
HDA Intel
USB Stream Output
bluealsa-play -l
**** List of PLAYBACK Bluetooth Devices ****
**** List of CAPTURE Bluetooth Devices ****
hci0: RA:ND:OM:MA:CA:DD [Phone], trusted phone
A2DP (SBC): S16_LE 2 channels 44100 Hz
bluealsa-play -L
bluealsa:DEV=RA:ND:OM:MA:CA:D2,PROFILE=a2dp,SRV=org.bluealsa
Phone, trusted phone, capture
A2DP (SBC): S16_LE 2 channels 44100 Hz
For now I'm trying the fifo way, but maybe the alsa one is cleaner? right now there's no configured /etc/asound.conf, maybe I'm missing something there?
To capture audio from a phone, you need arecord
not aplay
, just as you would if you were capturing from a sound card. You will also need to take care of the sample rate, sample format and channel count, just as you would if capturing from a sound card.
that makes sense, I'll play around that way, thank you so much. After that how can I costantly play, non interactively, from the PCM to a fifo?
I think this is wandering off-topic a little now. You are actually asking "How do I play audio from an ALSA capture device using snapcast" ( because a BlueALSA device is just like any other ALSA device ); and so I think the best place to ask is on a snapcast forum (or perhaps the answer is already in the snapcast documentation).
I expressed myself poorly, I was looking for a way obtain the same effect of arecord
through an /etc/asound.conf file maybe, I've see that it can output to a file (fifo), right? how that works under bluealsa?
I tried with this in asound.conf but to no avail
pcm.!default {
type file
slave {
pcm "bluealsa"
}
file "/tmp/snapfifo"
format "raw"
}
but I got a little victory with the interactive way and it now works perfectly!
arecord -D bluealsa -f s16_le -c 2 -r 48000 > /tmp/snapfifo
let me know if this is still off topic and thank you so much for the support
OK, so as you seem reluctant to ask for help from the snapcast project, I've had a quick look at the snapcast docs, and installed snapserver and snapclient on my own machine.
I defined the default source in the file /etc/snapserver.conf
as:
source = alsa://?name=default&device=bluealsa
I added the _snapserver
user to the audio
group and then reloaded the dbus config so that the snap sever has permission to use bluealsa:
sudo systemctl reload dbus
I restarted the snapserver service:
sudo systemctl restart snapserver.service
I started the snapclient
service:
sudo systemctl start snapclient.service
I then connected my 'phone, started music playback, and immediately the music played through my computer speakers. No need for /etc/asoundrc
or any applications other than snapserver
and snapclient
. Easy.
source = alsa://?name=default&device=bluealsa
that bit helped me greatly to sort my problem out without the overhead of the fifo source (I'm running in a containerized env), thank you!
Unfortunately, while the stream is playing, I´m facing continuous dropouts, would raising the PCM buffer help to solve this?
pcm.buffered {
type plug
slave.pcm {
type bluealsa
device "XX:XX:XX:XX:XX:XX"
profile "a2dp"
buffer_size 256000
}
}
source = alsa://?name=default&device=buffered
would that even work? I'm trying to wrap my head around the audio flow when working with PCMs
@borine have you encountered this kind of issue related to PCM direct play (without pulseaudio or pipewire)? I excluded external interference like wifi and tried to setup without containers and the problem still there
after a night of testing, I was able to boil the problem down a bit:
I enabled the loopback
modprobe snd-aloop
Used bluealsa-aplay to play audio from the bluetooth device to the loopback out pcm device
bluealsa-aplay --pcm=hw:1,0
Now I the dropouts are far less and in between and when those happens the bluealsa-aplay command gives me this errors
bluealsa-aplay: [663105] D: aplay.c:540: Starting IO loop
bluealsa-aplay: [663105] D: aplay.c:664: Opening ALSA playback PCM: name=hw:1,0 channels=2 rate=44100
bluealsa-aplay: [663105] D: aplay.c:679: Opening ALSA mixer: name=default elem=Master index=0
bluealsa-aplay: [663105] W: aplay.c:683: Couldn't open ALSA mixer: Mixer element not found
bluealsa-aplay: [663105] D: aplay.c:578: BT device marked as inactive: XX:XX:XX:XX:XX:XX
bluealsa-aplay: [663105] D: aplay.c:664: Opening ALSA playback PCM: name=hw:1,0 channels=2 rate=44100
bluealsa-aplay: [663105] D: aplay.c:679: Opening ALSA mixer: name=default elem=Master index=0
bluealsa-aplay: [663105] W: aplay.c:683: Couldn't open ALSA mixer: Mixer element not found
bluealsa-aplay: [663105] D: aplay.c:578: BT device marked as inactive: XX:XX:XX:XX:XX:XX
what it does mean?
ps: should I open another issue for this?
D: aplay.c:578: BT device marked as inactive: XX:XX:XX:XX:XX:XX
It means that the audio has stopped coming from the remote BT device for more or equal to 500ms. In most cases it's long enough to generate PCM underrun anyway. So, in such case the output PCM is closed and bluealsa-aplay waits for incoming PCM samples from the remote BT device. If your ALSA PCM output device buffer is bigger than 500ms, then you can try to increase this timeout value: https://github.com/arkq/bluez-alsa/blob/87e55cdb2feca6c9136f0344de2d49859b468abf/utils/aplay/aplay.c#L745
thank you for that insight, I will inspect deeper that way.
I have one last doubt, I have two bluetooth devices and right now I'm streaming them each in a separate PCM loopback-in subdevice with a script, so I can reroute their PCM loopback-out to snapcast.
This is working
/usr/bin/bluealsa-aplay --pcm=hw:1,0,0 YY:XX:XX:XX:XX:XX &
/usr/bin/bluealsa-aplay --pcm=hw:1,0,1 XX:YY:XX:XX:XX:XX
but I would like to replicate this non interactively by creating PCMs devices through asound.conf. Bluealsa creates the pcm device on bluetooth connection so asound.conf would fail at boot if bluetooth device are not connected right? there's a cleaner way to achieve that?
thank you for your time
would that even work?
No, the bluelalsa
plugin type does not accept "buffer_size" as a parameter. See the bluealsa-plugins manual page for details of the BlueALSA PCM plugin.
have you encountered this kind of issue related to PCM direct play
I have never used snapcast
before, so can't say what to expect here. Occasional dropouts are not uncommon when reading from one PCM device and "live streaming" to another PCM device on a different sound card. That is because the timers on the two devices are never exactly synchronized, there is always some small drift between them. Some applications contain code to adjust the stream to compensate for this, others do not. Often increasing buffer size and/or start threshold can fix this well enough to play for a few hours without dropouts occuring.
However "continuous dropouts" is rarely due to timer drift because most modern timers are reasonably accurate. I have seen this when using the ALSA rate
plugin, especially in combination with the ALSA dmix
plugin. see the bluealsa-aplay manual page. I see that your phone is playing audio sampled at 44100; so the ALSA rate
plugin is being used here if snapserver
is configured to read its source at rate 48000
After playing with snapcast a little this morning, I see that it does not like alsa sources that do not guarantee a continuous stream. That is not uncommon, and at present there is no workaround for the bluealsa
plugin when used as a source. So perhaps my suggestion of using the snapserver alsa source was not the best after all.
One alternaive is to use bluealsa-aplay
with the pipe
source. I tested that successfully (no droputs) with the following setup:
/etc/asound.conf
pcm.snapserver {
type plug
slave {
rate 48000
format S16_LE
channels 2
pcm {
type file
file "/tmp/snapfifo"
format raw
slave.pcm null
}
}
}
/etc/snapserver.conf
source = pipe:///tmp/snapfifo?name=default&mode=create&sampleformat=48000:16:2&codec=pcm
bluealsa-aplay command line:
bluealsa-aplay --pcm=snapserver
Note that my phone is sending stereo, S16_LE sampled at 48000.
I will try the loopback solution later in the week and report back here. Meanwhile please can you post your /etc/snapserver.conf
source = ...
entry that you are using with the loopback solution (and also any /etc/asound.conf
entry associated with that).
that was a really great compendium and reading, thank you for that.
as for the alternatives to continuous streaming, I found out that using the loopback device instead of the fifo is more reliable in terms of latency, and to me (correct me if I'm guessing wrong) looks more of a streamlined approach using PCMs only. Beside that I'm puzzling over why using the loopback as a middle device solved all the dropouts issue altogether, it is because it add some kind of buffer? Have some patience please, this is my first serious approach to the audio driver world
my actual (working) snapserver.conf
source = alsa://?name=phone1&device=hw:1,1,0&sampleformat=44100:16:2&codec=pcm
source = alsa://?name=phone2&device=hw:1,1,1&sampleformat=44100:16:2&codec=pcm
My target is to have multiple snapcast group to separate bluetooth source devices; ideally this let me connect to the bluetooth adapter with multiple devices so I can choose on which snapclient each bt client will play
I'm puzzling over why using the loopback as a middle device solved all the dropouts
I can only guess that it is because you have explicitly set &sampleformat=44100:16:2
and used the hw
alsa plugin. That means there is no rate conversion anywhere in the chain.
I've now tried bluealsa-aplay
with both alsa Loopback and fifo sources and I seem to have very similar latency and no dropouts with either. So I would recommend to go with whichever works best for you.
beautiful, thank you all and keep up with this amazing project!