-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Routing audio to bluealsa from hw:0,1 #686
Comments
This concept is not new, but I'm afraid that ALSA still does not support such use case out of the box (I mean there is no plugin available which would allow such use case). I'm not sure how difficult would be to write such plugin for ALSA... It does not seems to be complicated (but of course devils is in the details). It could be hosted in the bluez-alsa repo, since such feature is mostly related to dynamically appearing/disappearing PCMs like Bluetooth and USB cards. My idea is as such: |
I assume Android does this at the system level but I don't even know if/how Android relates to ALSA. Otherwise, it is done by applications sniffing for udev/dbus signals. |
Yes, that's one way of doing it. @borine has created a script which does that and dynamically changes ALSA configuration: https://github.com/borine/bluealsa-autoconfig However, it does not allow to dynamically switch between PCMs. I think, that from the user point of view, the best way would be to create a dedicated software plugin which can be used as a default PCM on the system. From the user point of view this plugin could not fail at all. In case there are no available PCMs, it could redirect audio to EDIT: It's quite possible that such new plugin would work best in tandem with https://github.com/borine/bluealsa-autoconfig |
The dynamic switching would be the difficult part. And I suppose you would have to deal with the situation where BT audio is coming in via ba-aplay and perhaps the user wants to send it out via BT to another device? When one or both go down, what order do they reconnect in? |
I was thinking about a bit simpler setup :D In my mind the only part that we need to take care about is the output - not the input. In case when the input goes down, it's up to the application what to do. However, in case of output going down, we can handle it for the application - as if it would talk with the audio server. The application sees PCM which can be opened and written to, what happens then it's up to the plugin (audio server). Problematic might be switching between PCMs with different latencies - application might not liked the idea of audio going out of sync rapidly. |
What if there's no application? In OSMC we just pass BT audio from ba-aplay to the default sink in ALSA (or one defined by a user in alsa conf). Not pretty, as we have to wait for Kodi to release the sink and some phones won't let you adjust the volume. Just saying. You are the experts. |
so
I guess that is android phones. Bluez AVRCP implementation appears to be incompatible with Android. There is a Bluez patch linked in a recent BlueALSA issue to fix that (I don't have a note of it right now). The problem may be gone with Android 14, but so far we have had no confirmation one way or another, and I do not have any Android devices to test with.
Yes, perhaps one day BlueALSA will get multi-client support, but for now only one client per stream is permitted.
Yes, indeed I think an option to manage latency by holding a large buffer (and therefore always incurring a large latency) would be necessary. Not a problem for applications such as |
Do'oh! I thought the volume thing was mainly on iPhones. My ancient Android phone works fine. |
Hello, Could you confirm, Is it proper method to that ? Or Do we have any other mechanism to do that ? |
It really depends on what |
Thanks for the explanation.Is it any other way remove noise or loopback method to achieve this requirement ? |
Well, the simple answer is to use an audio server like pipewire or pulseaudio. If you are unable to use an audio server then you really have to learn a lot more about the basics of linux low-level audio streaming. This is not the right place to look for such detailed training. |
I found something here. For this requirement we can create Virtual PCM with subdevices using "sudo modprobe snd-aloop" and it will give you New card (card 1),devices (0,1) and 8 subdevices (0 to 7) for individual devices. Then, All music services need to open and write into Virtual pcm , say example (hw:1,0,4) instead of direct (hw:0,1) and we will get loopback on (hw:1,1,4), Here we can use "alsaloop" to capture from hw:1,1,4 and playback to required pcm . We can kill it and restart it dynamically based on the output selection. No need to disturb the audio writing music sources. Ref link : https://sysplay.in/blog/linux/2019/06/playing-with-alsa-loopback-devices/ |
Sure, there are some notes on using the But, if I was building a system with the specific requirement to automatically switch a running stream from sound card to bluetooth, my first choice would still be Pipewire. |
@borine Could you please explain me why pipewire will be your choice than bluealsa ? Does pulseaudio/pipewire better than bluealsa ? bluealsa will be plugin in this case, How pulseaudio and pipewire will be behaving in this case ? Kindly suggest me any blog/tutorial to study about it. Thanks |
Because the main issue discussed here is moving a running audio stream, uninterrupted, from one output device to another. This is outside the scope of ALSA. There is no ALSA tool for this. Whichever way you choose to combine different ALSA plugins and utilities you will always need to write some new code to actually achieve the change from one device to another. And to do that successfully such that it works well with many different applications is not trivial. BlueALSA sits behind the ALSA interface, so merely allow you to use a Bluetooth device as you would a sound card device. What you need is something that sits in front of the ALSA interface, between your applications and ALSA, which can provide the required additional functionality, before passing the resulting stream to ALSA. That is the role of an audio service, such as Pipewire. Now Pipewire also has its own Bluetooth audio solution, and Bluez does not permit two different services to both provide A2DP service. So when using Pipewire the best advice is to not use BlueALSA at all. It may be possible to use BlueALSA through Pipewire's ALSA backend (see for example #681) but I do not know of anyone who has managed to do it successfully yet, and I would not recommend it. I think it is a shame that there are no Linux audio servers that are designed to be able to use ALSA for all audio I/O, and not just for sound cards, but that is the reality at this time. So Pipewire is not "better" than BlueALSA, it is just a different tool designed for a different purpose. So by all means try out your alsaloop/snd-aloop solution, and if successful please do document it to share it with others, I think it would be very useful to many systems. I'm just thinking that you are commiting yourself to a lot of work to solve a problem that has already been solved by Pipewire (and by Pulseaudio) |
@borine Thanks for the detailed explanation. Do we have any audio player in pulseaudio like bluealsa-aplay ? |
I guess the nearest equivalent is the pulse module-loopback module or the pipewire libpipewire-module-loopback module. See the pulseaudio/pipewire/wireplumber docs and seek help from pulseaudio/pipewire/wireplumber forums |
I've created a very simple PoC ALSA plugin for dynamic PCM switching: https://github.com/arkq/alsa-plugin-dswitch It "works" with The concept is very simple. The plugin exposes common PCM interface which can be opened by any application. Then, when the PCM is started by the application, a real PCM is opened and all samples are forwarded to it. In case when the write returns @borine @graham8 what do you think about such concept? I'm not sure whether I'd be able to "finish" it to be useable, but maybe someone can develop it beyond simple PoC. The best idea would be to add such plugin to alsa-plugins repo, but I'm not sure whether such plugin can be generic enough to fit upstreaming criteria. The problem is that all the "backends" need to be behind |
That's a very interesting idea. I have some ideas on how to make the devices selectable from the ALSA config, and also on how to get rid of the "busy loop" for device detection. I'll raise PRs on the dswitch repo when I have some code ready, and suggest we use the issue list there also for general discussion. |
@borine, I have one doubt. In our system, All the other music source using alsa-lib like they open and write audio on snd_pcm() APIs, In this case , If i use pulseaudio for bluetooth, How can i achieve BT as audio source ? In bluealsa, As a plugin other music services can write into it. It will go to bluealsa daemon and send to bluetooth speaker. Here, How will be in pulseaudio with bluetooth ? Other music service needs to integrate with pulseaudio instead of ALSA api ? Sorry for this kind of basic questions. |
I did not mean to suggest that you use pulseaudio and bluealsa together. What I mean is that if you want live streams to be switched from one device to another without stopping, and without the music applications doing that themselves, then you need an audio server such as Pipewire or Pulseaudio. That is true even if you are not using Bluetooth. Suppose you want to redirect a running stream from an on-board sound card to a usb device when the usb one is plugged in. How would you do that with only ALSA? I think you cannot. So you need your applications to send their audio to an audio server which can do that task. Then the audio server uses its own bluetooth implementation and Bluealsa is not needed. |
Hi @borine, @arkq Here, If i check with BT speakers and neckband ,then the audio playback is fine, there is no glitch at all. "WARNING: from element /GstPipeline:pipeline0/GstAlsaSrc:alsasrc0: Can't record audio fast enough Even if i play using alsaloop also, I am getting this audio breaks issue with earbuds. I am not sure why this happens only with bluetooth earbuds? bluealsa version : 4.1.1 |
This may be related to the used codec and codec configuration. Please can you give the output of the following command when each of the bluetooth devices are connected so that we can compare the selected configurations for "BT speakers", "neckband" and "bluetooth ear buds":
|
**** List of PLAYBACK Bluetooth Devices **** **** List of PLAYBACK Bluetooth Devices **** **** List of PLAYBACK Bluetooth Devices **** I have verified with Many earbuds, But i am getting the audio breaks issue with some of them only. Let me know, If we need to change any configuration on codec, defaults.bluealsa.codec "SBC", |
Hmm, so something unexpected here. The config default codec is usually "unchanged" which allows the device and the bluealsa service to negotiate the best available codec. If you set this default to "SBC" then I would expect all devices to use SBC, I am surprised that the earbuds are using AAC.
Please can you verify, do all the non-working earbuds use AAC and all the working ones use SBC ? In any case, using a different codec should not in itself make the device consume samples more slowly. I was expecting to see the earbuds using a different rate (but all your devices are using 48000). I can think of two reasons why the bluetooth device may run more slowly than the hw capture device:
A possible fix for the first problem is to tell the application explicitly what sample rate to run the sink at (i.e. 48000). That way we can be sure that the libasound resampler is not being used by ALSA For the second problem you may find that increasing buffer sizes and/or latency may help. It depends entirely on how the application adjusts for clock drift between the devices. |
Working earbuds also using AAC codec only.
Is it expected that earbuds choose 48K always ? or Can we change it forcefully to 44.1k?
If this is a case, How come other BT speakers,Neckbands, and some earbuds too working without audio glitch ?
If i tell the application (i.e alsaloop) with rate 48000, it will do resampling inside the application, right ?, this resampling also will be done by libasound, Is it ?. Will it make issue again ?
I have increased the latency and checked with alsaloop application,even after i was getting the same issue.4 One more issue, One of my earbuds(JBL) using only one codec, I have connected and checked through phone, it was showing SBC codec only. If i connect and doing playback (as BT source with bluealsa plugin) with my device and tried "scan on" in bluetoothctl, at that time i was getting audio glitch issue. Normally, it works fine. |
You can tell bluealsa to use 44.1 whenever possible (see the bluealsa manual page), but I do not recommend it as 48k generally gives better results
If they are all using 2-channel s16_le at 48000 frames per second then most likely the ALSA rate plugin is not the cause of this problem.
It depends on the application, you will have to check each application you wish to use. For
there are some notes on using
Many users have reported such issues, but this is not a BlueALSA problem - you will experience the same with any bluez audio solution. My only advice is "do not do that". |
Thanks for the detailed responses @borine , Let me cover all possible test cases and come back with the results. |
Hi @borine , So, I can go with codec "unchanged" right ? I remember, i have tested with Marshall speaker as Sink device. At that time, audio was coming out with very low playback speed. For that reason only, i have set this codec as SBC by default, then it was fine. So i left it hci0: xx:xx:xx:xx:xx:xx [marshall], audio-card How can I avoid this problem by blocking of selecting 96000 rate ? |
I have enabled "bluealsa --a2dp-force-audio-cd" force 44.1k , After that, I am not getting low speed playback issue with Marshall too. Is it good idea to avoid that low speed playback issue ?
This issue, I am not seeing with other speakers,neckbands and earbuds but only with JBL earbuds. Could you please give some details to debug this issue ? |
Hi,
I have a issue with bluealsa while routing audio from hw. And my requirement is to redirect the audio from hw:0,1 to bluealsa. From that moment, Audio should not come through hw:0,1. Its like bluealsa needs to act as virtual plugin at runtime.
bluealsa version : 4.1.1
conf file : /bluez-alsa/src/asound/20-bluealsa.conf.in
OS : Linux username 5.4.210 #2 SMP PREEMPT Thu Feb 29 20:24:03 IST 2024 aarch64 GNU/Linux
BlueZ version : 5.72
For example,
--> If other music sources writes audio on hw:0,1, then if BT got connected it should redirect audio to bluealsa plugin without disturbing (closing pcm and reopen snd_pcm_open() with bluealsa plugin) other music services whoever writing audio.
--> alsaloop -C hw:0,1 -P bluealsa (or) arecord -D hw:0,1 -r 48000 -c 2 -f S16_LE | aplay -D bluealsa
I have tried above steps, I could hear audio mixed with noise. What is the issue here ?
I am new to Alsa and PCM . Any help will be appreciated. Thanks
The text was updated successfully, but these errors were encountered: