-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcombine-sinks
128 lines (104 loc) · 4.16 KB
/
combine-sinks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/bin/bash
# Script: combine-sinks
# Description: Manages PulseAudio/PipeWire sinks by creating a combined sink
# for multiple audio outputs.
#
# Usage: /usr/libexec/combine-sinks
# Set the necessary environment variables for PipeWire (or PulseAudio)
export PULSE_RUNTIME_PATH="/run/user/1000/pulse/"
export XDG_RUNTIME_DIR="/run/user/1000/"
# Set error handling
set -euo pipefail
OVOS_USER="$(getent passwd 1000 | cut -d: -f1)"
MK1_CARD_NAME="snd_rpi_proto" # Mark 1 soundcard
HDMI_CARD_NAME="vc4-hdmi" # HDMI soundcard
HEADPHONES_CARD_NAME="bcm2835" # Onboard soundcard, not available on rpi5
# Function to handle errors
error_handler() {
local line_no=$1
local error_code=$2
log_message "Error (code: ${error_code}) occurred on line ${line_no}"
exit ${error_code}
}
trap 'error_handler ${LINENO} $?' ERR
# Log function to write to a log file
# Args:
# $1: Message to log
log_message() {
echo "$1"
echo "$(date) - $1" >> /tmp/autosink.log
}
log_message "Setting up audio output as combined sinks"
if [ "$EUID" -eq 0 ]; then
log_message "Running as root"
else
log_message "Running as user"
fi
# Wait for the 'auto_null' sink if present (system booting phase)
if pactl list short sinks | grep -q "auto_null"; then
log_message "auto_null sink exists, still booting? Sleeping for 3 seconds..."
sleep 3
fi
# Check if the file exists before reading it
if [ -f /etc/OpenVoiceOS/i2c_platform ]; then
i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform)
log_message "ovos-i2csound detection: $i2c_platform"
else
log_message "/etc/OpenVoiceOS/i2c_platform not found."
i2c_platform=""
fi
# log mk1 related warnings just for info and debug
if echo "$i2c_platform" | grep -q "MARK1"; then
# If it's a Mark 1 device, configure the Mark 1 soundcard
# NOTE: sometimes errors here if early in boot process, it's fine as the .service retries on failure
if aplay -l | grep "$MK1_CARD_NAME"; then
CARD_NUMBER=$(aplay -l | grep "$MK1_CARD_NAME" | awk '{print $2}' | cut -d':' -f1)
log_message "Detected CARD_NUMBER for Mark 1 soundcard: $CARD_NUMBER"
else
log_message "Error: ovos-i2csound detected Mark1 but 'aplay -l' could not detect '$MK1_CARD_NAME'"
fi
fi
# Log the current sinks before any action
log_message "Sinks before action: $(pactl list short sinks)"
# Get all sinks, excluding 'auto_combined' and 'auto_null'
# NOTE: sometimes errors here if early in boot process, its fine as the .service retries on failure
SINKS=$(pactl list short sinks | awk '{print $2}' | grep -v 'auto_combined' | grep -v 'auto_null' | tr '\n' ',' | sed 's/,$//')
NUM_SINKS=$(echo "$SINKS" | tr ',' '\n' | wc -l)
# Retry logic if no sinks are found
RETRIES=5
while [ "$NUM_SINKS" -eq 0 ] && [ "$RETRIES" -gt 0 ]; do
log_message "Retrying to find sinks... ($RETRIES retries left)"
sleep 1
RETRIES=$((RETRIES - 1))
SINKS=$(pactl list short sinks | awk '{print $2}' | grep -v 'auto_combined' | grep -v 'auto_null' | tr '\n' ',' | sed 's/,$//')
NUM_SINKS=$(echo "$SINKS" | tr ',' '\n' | wc -l)
done
# Check if auto_combined is present
if pactl list short sinks | grep -q "auto_combined"; then
log_message "auto_combined sink exists"
else
log_message "auto_combined sink missing"
fi
log_message "Total sinks: $NUM_SINKS"
# Create a combined sink if there is more than one sink
if [ "$NUM_SINKS" -gt 1 ]; then
# Unload any existing combined sink module
pactl unload-module module-combine-sink 2>/dev/null
# Create a new combined sink with all available sinks
if ! MODULE_ID=$(pactl load-module module-combine-sink slaves="$SINKS" sink_name=auto_combined); then
log_message "Failed to create combined sink"
exit 1
fi
# Verify the sink exists before setting as default
if pactl list short sinks | grep -q "auto_combined"; then
pactl set-default-sink auto_combined
log_message "Combined sink created with outputs: $SINKS (module ID: $MODULE_ID)"
else
log_message "Combined sink creation failed"
exit 1
fi
else
log_message "No sinks found to combine"
fi
# Log the current sinks after action
log_message "Sinks after action: $(pactl list short sinks)"