Skip to content

Instantly share code, notes, and snippets.

@OndraZizka
Last active May 29, 2024 13:43
Show Gist options
  • Save OndraZizka/2724d353f695dacd73a50883dfdf0fc6 to your computer and use it in GitHub Desktop.
Save OndraZizka/2724d353f695dacd73a50883dfdf0fc6 to your computer and use it in GitHub Desktop.
Bluetooth headset - switch between quality sound + no mic (A2DP) and crappy sound and mic (HSP/HFP)
#!/bin/bash
#### Restart Bluetooth
if [ "$1" == "resetBT" ] ; then
sudo rfkill block bluetooth && sleep 0.1 && sudo rfkill unblock bluetooth;
exit;
fi;
#### Toggle listen/speak
if [ "$1" == "" -o "$1" == "toggle" ] ; then
LINE=`pacmd list-sinks | grep '\(name:\|alias\)' | grep -B1 F5A | head -1`
if [ "$LINE" == "" ] ; then echo "F5A headset not found."; $0 reset; sleep 2; exit; fi
SINK_NAME="bluez_sink.00_19_5D_25_6F_6C.a2dp_sink"
if $(echo "$LINE" | grep $SINK_NAME &> /dev/null) ; then
echo "Detected quality sound output, that means we can't speak; switch that."
$0 speak;
else
echo "Quality sound not found, switch to the good sound."
$0 listen;
fi
fi
#### Change the output to F5A
if [ "$1" == "listen" ] ; then
LINE=`pacmd list-sinks | grep '\(name:\|alias\)' | grep -B1 F5A | head -1`
if [ "$LINE" == "" ] ; then echo "F5A phones not found."; $0 reset; sleep 2; exit; fi
# name: <bluez_sink.00_19_5D_25_6F_6C.headset_head_unit>
## Get what's between <...>
SINK_NAME=`echo "$LINE" | tr '>' '<' | cut -d'<' -f2`;
## The above gives an ID according to the active profile.
## To set manually:
#SINK_NAME="bluez_sink.00_19_5D_25_6F_6C.headset_head_unit"
#SINK_NAME="bluez_sink.00_19_5D_25_6F_6C.a2dp_sink"
## Switch the output to that.
echo "Switching audio output to $SINK_NAME";
pacmd set-default-sink "$SINK_NAME"
#### Change profile to quality output + no mic. From `pacmd list-cards`:
CARD="bluez_card.00_19_5D_25_6F_6C"
PROFILE="a2dp_sink"
echo "Switching audio profile to $PROFILE";
pacmd set-card-profile $CARD $PROFILE
exit;
fi;
#### Input
if [ "$1" == "speak" ] ; then
## Change profile to crappy output + mic. From `pacmd list-cards`:
CARD="bluez_card.00_19_5D_25_6F_6C"
pacmd set-card-profile $CARD headset_head_unit
LINE=`pacmd list-sources | grep '\(name:\|alias\)' | grep -B1 F5A | head -1`
if [ "$LINE" == "" ] ; then echo "F5A mic not found."; $0 reset; sleep 2; exit; fi
SOURCE_NAME=`echo "$LINE" | tr '>' '<' | cut -d'<' -f2`;
#SOURCE_NAME="bluez_source.00_19_5D_25_6F_6C.headset_head_unit"
#SOURCE_NAME="bluez_sink.00_19_5D_25_6F_6C.a2dp_sink.monitor"
echo "Switching audio input to $SOURCE_NAME";
pacmd set-default-source "$SOURCE_NAME" || echo 'Try `pacmd list-sources`.';
fi;
#### Resources:
## Why this is needed
# https://jimshaver.net/2015/03/31/going-a2dp-only-on-linux/
## My original question
# https://askubuntu.com/questions/1004712/audio-profile-changes-automatically-to-hsp-bad-quality-when-i-change-input-to/1009156#1009156
## Script to monitor plugged earphones and switch when unplugged (Ubuntu does that, but nice script):
# https://github.com/freundTech/linux-helper-scripts/blob/master/padevswitch/padevswitch
@Fuzzphorescent
Copy link

@JustinFrost47 I never did figure it out but now having read your answer, it seems so obvious what the problem was. Looks like I hadn't skimmed the code back then to find out what prompted the error message.

I've since moved to a newer machine running Windows 10 (which is posing its own set of BT-related challenges). I'm now inspired to dust off the old laptop and give it another go for an undeserved sense of accomplishment. Thanks for the help, cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment