Created
January 22, 2026 18:20
-
-
Save Interpause/fc7bb9cf6fb91d2582f71c19abf60389 to your computer and use it in GitHub Desktop.
Vibecoded Bash Script to Check SBC Bitpool & Bitrate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Thanks gemini | |
| # Also since im on Gentoo, this DOESN't need systemd! (Should work on systemd still I think) | |
| set -eo pipefail | |
| # Dependency check | |
| if ! command -v busctl &> /dev/null; then | |
| echo "Error: 'busctl' is not installed." | |
| exit 1 | |
| fi | |
| echo "Scanning for Bluetooth Audio Transports..." | |
| echo "----------------------------------------------------------------------------------------------------" | |
| printf "%-25s | %-12s | %-10s | %-30s\n" "Device Address" "Status" "Codec" "Details / Bitrate" | |
| echo "----------------------------------------------------------------------------------------------------" | |
| # 1. Find all Transport paths | |
| # We use grep -oE to reliably grab the path ending in fdX | |
| mapfile -t paths < <(busctl --system tree org.bluez | grep -oE '/org/bluez/.*fd[0-9]+') | |
| if [ ${#paths[@]} -eq 0 ]; then | |
| echo "No audio transports found. Ensure headphones are connected." | |
| exit 0 | |
| fi | |
| for path in "${paths[@]}"; do | |
| # Extract clean MAC address for display | |
| device_addr=$(echo "$path" | grep -o 'dev_[^/]*' | sed 's/dev_//;s/_/:/g') | |
| # 2. Get State | |
| # CHANGED: 'get' -> 'get-property', removed 2>/dev/null | |
| # We use || true so the script doesn't crash if a device disconnects mid-loop | |
| raw_state=$(busctl --system get-property org.bluez "$path" org.bluez.MediaTransport1 State || true) | |
| if [[ -z "$raw_state" ]]; then | |
| printf "%-25s | %-12s | %-10s | %-30s\n" "$device_addr" "ERROR" "-" "Device vanished or call failed" | |
| continue | |
| fi | |
| # Parse: Output is usually 's "active"' | |
| state=$(echo "$raw_state" | cut -d' ' -f2 | tr -d '"') | |
| # 3. Get Codec ID | |
| # CHANGED: 'get' -> 'get-property' | |
| raw_codec=$(busctl --system get-property org.bluez "$path" org.bluez.MediaTransport1 Codec) | |
| codec_id=$(echo "$raw_codec" | cut -d' ' -f2) | |
| # Determine Codec Name | |
| case "$codec_id" in | |
| 0) codec_name="SBC" ;; | |
| 1) codec_name="MPEG" ;; | |
| 2) codec_name="AAC" ;; | |
| 255) codec_name="Vendor" ;; | |
| *) codec_name="ID:$codec_id" ;; | |
| esac | |
| # --- CHECK: IDLE --- | |
| if [[ "$state" != "active" ]]; then | |
| printf "%-25s | %-12s | %-10s | %-30s\n" "$device_addr" "IDLE" "$codec_name" "Stream paused/inactive" | |
| continue | |
| fi | |
| # --- CHECK: NON-SBC --- | |
| if [[ "$codec_id" != "0" ]]; then | |
| printf "%-25s | %-12s | %-10s | %-30s\n" "$device_addr" "ACTIVE" "$codec_name" "Not SBC (Skipping calc)" | |
| continue | |
| fi | |
| # 4. Parse SBC Configuration | |
| # CHANGED: 'get' -> 'get-property' | |
| raw_config=$(busctl --system get-property org.bluez "$path" org.bluez.MediaTransport1 Configuration) | |
| # Output is like: "ay 4 20 21 53 53" | |
| # We want everything after the 3rd space to get the bytes | |
| config_bytes=$(echo "$raw_config" | cut -d' ' -f3-) | |
| read -r -a config_arr <<< "$config_bytes" | |
| # --- DECODE SBC --- | |
| # Byte 0: Frequency & Channel Mode | |
| b0=${config_arr[0]} | |
| if (( (b0 & 16) )); then freq=48000; freq_str="48kHz" | |
| elif (( (b0 & 32) )); then freq=44100; freq_str="44.1kHz" | |
| elif (( (b0 & 64) )); then freq=32000; freq_str="32kHz" | |
| else freq=16000; freq_str="16kHz"; fi | |
| if (( (b0 & 1) )); then ch_mode="JointStereo"; channels=2; join=1 | |
| elif (( (b0 & 2) )); then ch_mode="Stereo"; channels=2; join=0 | |
| elif (( (b0 & 4) )); then ch_mode="DualChannel"; channels=2; join=0 | |
| else ch_mode="Mono"; channels=1; join=0; fi | |
| # Byte 1: Blocks, Subbands | |
| b1=${config_arr[1]} | |
| if (( (b1 & 16) )); then blocks=16 | |
| elif (( (b1 & 32) )); then blocks=12 | |
| elif (( (b1 & 64) )); then blocks=8 | |
| else blocks=4; fi | |
| if (( (b1 & 4) )); then subbands=8 | |
| else subbands=4; fi | |
| # Byte 3: Max Bitpool | |
| bitpool=${config_arr[3]} | |
| # --- CALCULATE BITRATE --- | |
| header_part=$(( 4 + (4 * subbands * channels) / 8 )) | |
| if [[ "$ch_mode" == "DualChannel" ]] || [[ "$ch_mode" == "Mono" ]]; then | |
| bits_payload=$(( blocks * channels * bitpool )) | |
| else | |
| bits_payload=$(( (join * subbands) + (blocks * bitpool) )) | |
| fi | |
| payload_bytes=$(( (bits_payload + 7) / 8 )) | |
| frame_len=$(( header_part + payload_bytes )) | |
| bitrate_bps=$(( (8 * frame_len * freq) / (subbands * blocks) )) | |
| bitrate_kbps=$(( bitrate_bps / 1000 )) | |
| # Print Active SBC Row | |
| info_str="BP:$bitpool | $ch_mode | $freq khz | $bitrate_kbps kbps" | |
| printf "%-25s | %-12s | %-10s | %-30s\n" "$device_addr" "ACTIVE" "$codec_name" "$info_str" | |
| done |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I just manually edited and applied https://github.com/ezrakhuzadi/bluetooth-bitrate-manager/blob/e300d7e1ee3857132a4c43d23c96c122c17968d2/bluetooth_bitrate_manager/resources/pipewire-sbc-custom-bitpool.patch lol
Didn't want it messing with directly installing over when I already have Gentoo's extremely convenient patching system.