karlstav / cava

Cross-platform Audio Visualizer
MIT License
4.32k stars 233 forks source link

Launching Cava changes bluetooth profile when using a bluetooth speaker with microphone #586

Open tannerellen opened 2 months ago

tannerellen commented 2 months ago

READ THIS BEFORE CREATING NEW ISSUE

Are you using cava from a package repository, like AUR?

I tested this on the latest using git clone and then building but it also affects the AUR version as well.

Describe the bug

On Arch Linux using Pipewire audio if I have audio playing through a bluetooth speaker that contains a microphone it will default to the A2DP bluetooth audio profile. If I then launch cava it will immediately change to an HSP headset audio profile.

This means that if music is playing everything sounds great, as soon as Cava is launched the audio quality is greatly reduced. I can manually switch the audio profile back but no other app causes this profile switch.

To Reproduce

Steps to reproduce the behavior:

  1. Default config
  2. Play audio through bluetooth speaker that also contains a microphone (or use a bluetooth headset).
  3. Make sure audio profile is A2DP
  4. Launch Cava
  5. See issue that bluetooth profile switches to a headset profile and audio quality is bad

Expected behavior

I would expect that the bluetooth audio profile doesn't change.

Screenshots

If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Terminal emulator

Additional context I'm using this in Hyprland window manager on Arch. using bluez, bluez-utils, and blueman for bluetooth connectivity.

platz-halter commented 2 months ago

I have the same configuration and the same problem. Pavucontrol also crashes when starting cava and displays this error:

ERROR:../pavucontrol/src/streamwidget.cc:110:void StreamWidget::setVolume(const pa_cvolume&, bool): assertion failed: (v.channels == channelMap.channels)
Bail out! ERROR:../pavucontrol/src/streamwidget.cc:110:void StreamWidget::setVolume(const pa_cvolume&, bool): assertion failed: (v.channels == channelMap.channels)
[1]    6882 IOT instruction (core dumped)  pavucontrol
karlstav commented 2 months ago

i have no idea why the profile would change. cava just tries to record from whatever is the default sink. I have no bluetooth device at hand to attempt repro

tried running pavucontrol and launching cava just now and it did not crash.

tannerellen commented 2 months ago

Ok, this is probably an issue further upstream then. I did a bit more digging and I think this is probably related to how wireplumber handles auto switching to headset profiles. So maybe this isn't so much a bug but just not ideal behavior with the interaction of the monitor source and wireplumber. It is a bit odd that cava triggers this and other apps don't but I did launch OBS and it momentarily switches to a headset profile, but then immediately switches back to A2DP.

In the meantime I am just disabling the auto switching behavior itself in my wireplumber config. For anyone that wants to do the same I added a config file in ~/.config/wireplumber/wireplumber.conf.d/80-policy.conf

with the contents:

wireplumber.settings = {
    bluetooth.autoswitch-to-headset-profile = false
}

I don't experience any crashes with pavucontrol so that is a separate issue.

Feel free to close this if you don't believe there is anything under cava control here.

karlstav commented 2 months ago

I can leave it open for now, maybe there is something to do. I have no bluetooth on my current setup, but if i remember it I will check next time i have to dig my laptop out.

platz-halter commented 1 month ago

I use pulseaudio trough pipewire-pulse. The change of audio profile only happens when the first instance of cava is started. Afterwards I can change the profile back manually and when starting a second instance it stays on the default(AAC) profile.

BirbIrl commented 1 month ago

for anyone on nixos, to disable your headset mode-auto-switching (on pipewire) is: services.pipewire.wireplumber.extraConfig."11-bluetooth-policy" = {"wireplumber.settings" = {"bluetooth.autoswitch-to-headset-profile" = false;};}; and save yourself time by just restarting wireplumber instead of the entire pc when testing with systemctl --user restart wireplumber.service This has saved me from several ear piercing "Ding-DINGS!!!" when using cava, booting wine games and the like. cheers :)

froopy090 commented 1 month ago

I have this same issue on Arch (Gnome with Wayland)

ambertia commented 1 month ago

I have the same issue on Arch Hyprland with bluez, blueman, and pipewire/wireplumber. Whenever cava was started the first time in a user session, it would auto-switch my bluetooth earbuds to an HSP audio profile. When I manually changed the codec back to an A2DP sink codec (specifically AAC), subsequent launches of the application would result in the codec changing to HSP for a few (i.e. ~3) seconds before switching back to AAC.

I managed a kind of brute-force solution by creating a config for the wireplumber BlueZ monitor plugin. I wrote it to ~/.config/wireplumber/wireplumber.conf.d/81-headset-disable.conf (though the exact file name shouldn't matter), and the only thing I changed from the example in the documentation is removing hsp-hs, hsp-ag, hfp-hf, and hfp-ag from bluez.roles. I don't particularly like it since this does disable bluetooth headset profiles entirely, but honestly I never even use bluetooth headphone mics because the headset codecs are such a drastic drop in quality anyway.

Remembering at the last second re-reading the thread before posting! I didn't connect the dots because I only play games on my desktop, but this very similar thing happens on my desktop (pretty stock Garuda linux - Arch with IIRC still bluez, blueman, and pipewire/wireplumber, except the DE is KDE6 and I'm in Wayland mode) when I launch games using Proton/Wine, especially in fullscreen windows. I have no clue why it happens but the behavior is so uncannily similar.

TL;DR I concur with the sentiment that it's probably upstream, there are brute-force solutions folks can use in this thread, and I'm going to go make the same config on my desktop so it stops happening during game launches :P

Edit: I made the same file on my desktop and it fixed my issue there (although for my headphones I use on desktop I use aptX HD, so I re-enabled a handful of aptX codecs on my desktop)

poseidonai555 commented 1 month ago

I have been using cava on my desktop setup for a wire, arch linux with pipewire-pulse, and I have had numerous issues with pulse audio, meaning I am forced to use pipewire. I am having the exact same issue as listed above, and would really appreciate if you fixed it, as I love cava so much, and this makes me grimace and hesitate every time it comes to opening the app.

karlstav commented 1 month ago

has anyone tried connecting cava directly with the object.serial instead of just "auto"

if you are using wireplumber then use wpctl status to get the ID of your device and then wpctl inspect ID to find the "object.serial", set the value as the source in cava config.

iiTzSeb commented 1 month ago

Also having the same issue. Running Arch@Hyprland, bluez, pipewire, wireplumber.

Though, unlike previous mentions/user experiences, when I launch cava while an audio source is playing it switches profiles to the headset profile and doesn't return to the original one after any amount of time. Just seems to stay on the headset profile and sounds like absolute garbage. Not entirely sure what the easiest/most appropriate fix is for this one.

karlstav commented 4 weeks ago

I finally had time to dig out the old laptop. I installed arch and hyprland on it as it seems to be what the majority here are using. Let me just say I really like it so far. They didn't make installing arch any easier than it was last time I tried 10 years ago though, but I guess that's there thing.

I was able to reproduce the issue right away, there is also a audible "bip" in the headset when cava is launched as to indicate that "something changed" and it goes over to the heavily compressed HSP audio. However, the exact same thing happens when launching pw-record. Also it is the same behavior when specifying the serial to the sink.

The workaround proposed above does work fine. That is our best option so far.

Next step would be opening an issue over at pipewire. This issue seems related, maybe pipewire can't tell the difference between someone asking for a mic source and the monitor source?