distribution/packages/jelos/sources/scripts/set-audio
fewtarius ed8438a7fc
* Update set-audio to configure alsa for bluetooth.
* Updaet set-audio to automatically populate the ES audio path with a best guess (first control).
* Enable pulseaudio bluetooth support.
* Don't reset audio devices and paths if they've already been set once.
* Configure CEMU to look for and use a bluetooth device if it's paired and connected (needs further optimization).
2023-01-26 17:51:43 -05:00

341 lines
7.1 KiB
Bash
Executable file

#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2020-present Fewtarius
. /etc/profile
ES_SETTINGS="/storage/.config/emulationstation/es_settings.cfg"
SETTINGS_CACHE="/storage/.cache/audio"
function save_state()
{
if [ ! -d "${SETTINGS_CACHE}" ]
then
mkdir -p ${SETTINGS_CACHE}
fi
get_audio_device >${SETTINGS_CACHE}/active_device
get_es_path >${SETTINGS_CACHE}/active_path
cp -f /storage/.config/asound.conf ${SETTINGS_CACHE}/asound.conf
cp -f /storage/.config/asound.state ${SETTINGS_CACHE}/asound.state
}
function restore_state()
{
if [ -e "${SETTINGS_CACHE}/asound.conf" ]
then
cp -f ${SETTINGS_CACHE}/asound.conf /storage/.config/
cp -f ${SETTINGS_CACHE}/asound.state /storage/.config/
set-audio esset "$(cat ${SETTINGS_CACHE}/active_path)"
set-audio set "$(cat ${SETTINGS_CACHE}/active_device)"
rm -f ${SETTINGS_CACHE}/{asound.conf,asound.state,active_path,active_device}
fi
}
function get_audio_device() {
MYAUDIODEVICE=$(get_setting system.audiodevice)
if [ ! -z "${MYAUDIODEVICE}" ]
then
echo ${MYAUDIODEVICE}
else
echo "DEFAULT (SYSTEM PROVIDED)"
fi
}
function get_es_path() {
AUDIODEVICE=$(grep AudioDevice ${ES_SETTINGS} | sed -e 's#^.*="##g' -e 's#"\ .*$##g')
if [ -z "${AUDIODEVICE}" ]
then
echo "DEFAULT (SYSTEM PROVIDED)"
else
echo "${AUDIODEVICE}"
fi
}
# Check if an audio device string corresponds to a bluetooth device
function is_bluetooth() {
if [[ "$1" =~ ^Device.* ]]
then
true
return
else
false
return
fi
}
function list_audio_controls() {
IFS=""
ACTIVE_DEVICE=$(get_audio_device)
if is_bluetooth "${ACTIVE_DEVICE}"
then
CONTROLS=$(amixer -D bluealsa controls | awk 'BEGIN {FS="'\''"} {print $2}')
else
CONTROLS=$(amixer scontrols | awk 'BEGIN {FS="'\''"} {print $2}')
fi
echo "DEFAULT (SYSTEM PROVIDED)"
echo "CUSTOM (UNMANAGED)"
for CONTROL in "${CONTROLS[@]}"
do
echo ${CONTROL} | awk '{print $1}' | grep -v -E 'Mic|Extension|Capture|Differential|Left|Right' | uniq
done
echo "--------"
for CONTROL in "${CONTROLS[@]}"
do
echo ${CONTROL}
done
}
function list_audio_devices() {
echo "DEFAULT (SYSTEM PROVIDED)"
echo "DEFAULT HDMI"
echo "BLUETOOTH DEVICE"
echo "CUSTOM (UNMANAGED)"
echo "--------"
BTACTIVE=$(systemctl is-active bluetooth)
if [ "${BTACTIVE}" == "active" ]
then
BTDEVICES=$(bluetoothctl devices Paired)
while read -r BTDEV
do
echo "${BTDEV}"
done <<< "${BTDEVICES}"
fi
for SDEVICE in $(find /proc/asound/card*/pcm*/info)
do
TYPE=$(awk '/^stream:/ {print $2}' ${SDEVICE})
if [[ "${TYPE}" =~ PLAYBACK ]]
then
CARD=$(awk '/^card:/ {print $2}' ${SDEVICE})
DEVICE=$(awk '/^device:/ {print $2}' ${SDEVICE})
NAME=$(awk '/^name:/ {print $2}' ${SDEVICE})
echo "${NAME} (${CARD}:${DEVICE})"
fi
done
}
function set_audio_device() {
SELECTION="$1"
# When switching from a non-bluetooth to a bluetooth device,
# store the last configuration in order to restore it on reboot.
if is_bluetooth "${SELECTION}"
then
ACTIVE_DEVICE=$(get_audio_device)
if ! is_bluetooth "${ACTIVE_DEVICE}"
then
save_state
fi
fi
set_setting system.audiodevice "${SELECTION}"
if [ "${SELECTION}" == "DEFAULT (SYSTEM PROVIDED)" ]
then
CARD="0"
HWDEV="hw:${CARD},0"
elif [ "${SELECTION}" == "DEFAULT HDMI" ]
then
CARD="0"
HWDEV="hdmi"
elif [ "${SELECTION}" == "BLUETOOTH DEVICE" ]
then
HWDEV="bluealsa"
elif [ "${SELECTION}" == "CUSTOM (UNMANAGED)" ]
then
exit 0
elif is_bluetooth "${SELECTION}"
then
MAC=$(echo "${SELECTION}" | awk '/^Device/ {print $2}')
# Reconnect device in case it auto-connected.
# This doesn't seem necessary anymore, re-activate in case of issues.
# bluetoothctl disconnect ${MAC}
if bluetoothctl connect ${MAC}
then
HWDEV="bluealsa"
fi
exit 0
else
if [ "${SELECTION}" == "--------" ]
then
exit 0
fi
for SDEVICE in $(find /proc/asound/card*/pcm*/info)
do
TYPE=$(awk '/^stream:/ {print $2}' ${SDEVICE})
if [[ "${TYPE}" =~ PLAYBACK ]]
then
CARD=$(awk '/^card:/ {print $2}' ${SDEVICE})
DEVICE=$(awk '/^device:/ {print $2}' ${SDEVICE})
NAME=$(awk '/^name:/ {print $2}' ${SDEVICE})
if [ "${SELECTION}" == "${NAME} (${CARD}:${DEVICE})" ]
then
HWDEV="hw:${CARD},${DEVICE}"
fi
fi
done
fi
if [[ "${HWDEV}" =~ ^hw ]]
then
cat <<EOF >/storage/.config/asound.conf
ctl.!default {
type hw
card ${CARD}
}
pcm.!default {
type plug
slave.pcm "softvol"
}
pcm.softvol {
type softvol
slave.pcm "dmixer"
control {
name "Pre-Amp"
card ${CARD}
}
min_dB -5.0
max_dB 20.0
resolution 6
}
pcm.dmixer {
type dmix
ipc_key 1024
slave {
pcm "${HWDEV}"
period_time 0
period_size 4096
buffer_size 131072
rate 176400
}
bindings {
0 0
1 1
}
}
EOF
elif [[ "${HWDEV}" =~ bluealsa ]]
then
cat <<EOF >/storage/.config/asound.conf
ctl.!default {
type hw
card 0
}
pcm.!default {
type plug
slave.pcm "softvol"
}
pcm.softvol {
type softvol
slave.pcm "dmixer"
control {
name "Pre-Amp"
card 0
}
min_dB -5.0
max_dB 20.0
resolution 6
}
pcm.dmixer {
type asym
capture.pcm cards.pcm.default
playback.pcm bluealsa
hint.description "Bluetooth Audio Device"
}
EOF
else
cat <<EOF >/storage/.config/asound.conf
pcm.!default {
type plug
slave {
pcm "softvol"
}
}
pcm.softvol {
type softvol
slave.pcm "dmixer"
control {
name "Pre-Amp"
card ${CARD}
}
min_dB -5.0
max_dB 20.0
resolution 6
}
ctl.!default {
type hw
card ${CARD}
}
EOF
fi
set-audio esset $(set-audio firstcontrol)
}
function set_es_path() {
AUDIODEVICE=${1}
if [ "${AUDIODEVICE}" == "CUSTOM (UNMANAGED)" ] || \
[ "${AUDIODEVICE}" == "--------" ]
then
exit 0
fi
AUDIOTEST=$(grep "AudioDevice" ${ES_SETTINGS} 2>/dev/null)
sed -i '/^.*<string name="AudioDevice".*$/d' ${ES_SETTINGS}
if [ -e "/storage/.config/profile.d/99-mixer" ]
then
rm "/storage/.config/profile.d/99-mixer"
fi
if [ ! "${AUDIODEVICE}" = "DEFAULT (SYSTEM PROVIDED)" ]
then
sed -i '/^.*AudioCard.*$/a \\t<string name="AudioDevice" value="'"${AUDIODEVICE}"'" \/>' ${ES_SETTINGS}
echo "DEVICE_AUDIO_MIXER=\"${AUDIODEVICE}\"" >/storage/.config/profile.d/99-mixer
if [ "${DEVICE_VOLUMECTL}" = true ]
then
systemctl restart volume
fi
fi
}
function assumed_control() {
ACTIVE_DEVICE=$(get_audio_device)
if is_bluetooth "${ACTIVE_DEVICE}"
then
ACONTROLS=$(amixer -D bluealsa controls | awk 'BEGIN {FS="'\''"} {print $2}')
else
ACONTROLS=$(amixer scontrols | awk 'BEGIN {FS="'\''"} {print $2}')
fi
echo ${ACONTROLS} | awk '{print $1}'
}
case $1 in
controls)
list_audio_controls
;;
list)
list_audio_devices
;;
set)
set_audio_device "$2"
;;
esset)
set_es_path "$2"
;;
get)
get_audio_device
;;
firstcontrol)
assumed_control
;;
esget)
get_es_path
;;
save)
save_state
;;
restore)
restore_state
;;
esac