ed8438a7fc
* 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).
341 lines
7.1 KiB
Bash
Executable file
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
|