From 2751aaba1f4239ecc61426286bab72fd3c11ecda Mon Sep 17 00:00:00 2001 From: miro Date: Sat, 18 Jan 2025 23:37:40 +0000 Subject: [PATCH 1/6] refactor soundcard_autoconfigure to use functions for each card easier to maintain --- soundcard_autoconfigure | 87 +++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/soundcard_autoconfigure b/soundcard_autoconfigure index 614c3ad..0b1c132 100644 --- a/soundcard_autoconfigure +++ b/soundcard_autoconfigure @@ -11,6 +11,8 @@ SOUND_SERVER="pipewire" # TODO: Add support for pulseaudio 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 +GOOGLE_VOICEKIT_V1 = "snd_rpi_googlevoicehat" # cant be autodetected by ovos-i2csound , user manually enables it +RESPEAKER_2MIC = "wm8960-soundcard" # Environment variables for PipeWire (or PulseAudio) export PULSE_RUNTIME_PATH="/run/user/1000/pulse/" @@ -138,26 +140,20 @@ get_sink_name_from_card() { # Wait for ovos-i2csound to complete setup sleep 1 -# Read platform information -if [ -f /etc/OpenVoiceOS/i2c_platform ]; then - i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform) -else - log_message "/etc/OpenVoiceOS/i2c_platform not found." - i2c_platform="" -fi - -log_message "$(aplay -l)" # Log detected soundcards -# Handle Mark 1-specific warnings -if echo "$i2c_platform" | grep -q "WM8960"; then - # If it's a Mark 1 device, check for arduino boot failure symptoms - # WM8960 is wrongly detected by ovos-i2csound if mk1 fails to load - log_message "WARNING [Mark1 only]: If this is a Mark 1 device, Arduino may not have booted properly. Power cycle your device until the eyes spin." -fi +setup_wm8960_soundcard() { + log_message "Respeaker-2mic (wm8960) detected by ovos-i2csound." + if aplay -l | grep "$RESPEAKER_2MIC"; then + CARD_NUMBER=$(aplay -l | grep "$RESPEAKER_2MIC" | awk '{print $2}' | cut -d':' -f1) + log_message "Detected CARD_NUMBER for Respeaker-2mic soundcard: $CARD_NUMBER" + set_alsa_defaults "$CARD_NUMBER" + else + log_message "Error: ovos-i2csound detected Respeaker-2mic but 'aplay -l' could not detect '$RESPEAKER_2MIC'" + exit 1 + fi +} -# Autoconfigure default soundcard -if echo "$i2c_platform" | grep -q "MARK1"; then - # If it's a Mark 1 device, configure the Mark 1 soundcard +setup_mark1_soundcard() { log_message "Mark 1 soundcard detected by ovos-i2csound." if aplay -l | grep "$MK1_CARD_NAME"; then CARD_NUMBER=$(aplay -l | grep "$MK1_CARD_NAME" | awk '{print $2}' | cut -d':' -f1) @@ -167,17 +163,31 @@ if echo "$i2c_platform" | grep -q "MARK1"; then log_message "Error: ovos-i2csound detected Mark 1 but 'aplay -l' could not detect '$MK1_CARD_NAME'" exit 1 fi -else +} + +setup_googlevoicekitv1_soundcard() { + # NOTE: special case, not detected by ovos-i2csound (yet) + # just a placeholder, ovos-i2csound will need to grep boot/config.txt to check if overlay is enabled + log_message "GoogleVoiceKit soundcard configured by user" + if aplay -l | grep "$GOOGLE_VOICEKIT_V1"; then + CARD_NUMBER=$(aplay -l | grep "$MK1_CARD_NAME" | awk '{print $2}' | cut -d':' -f1) + log_message "Detected CARD_NUMBER for GoogleVoiceKit soundcard: $CARD_NUMBER" + set_alsa_defaults "$CARD_NUMBER" + else + log_message "Error: user configured GoogleVoiceKit but 'aplay -l' could not detect '$GOOGLE_VOICEKIT_V1'" + exit 1 + fi +} + +setup_fallback_soundcard() { # Check for USB soundcard if aplay -l | grep "card" | grep -i "usb"; then USB_CARDS=$(aplay -l | grep "card" | grep -i "usb" | awk '{print $2}' | cut -d':' -f1) if [ -n "$USB_CARDS" ]; then - # If multiple USB soundcards are detected, log a warning and pick the last one CARD_COUNT=$(echo "$USB_CARDS" | wc -l) if [ "$CARD_COUNT" -gt 1 ]; then log_message "Warning: Multiple USB soundcards detected. Using the last detected card." fi - # Select the last USB soundcard detected USB_CARD=$(echo "$USB_CARDS" | tail -n 1) else USB_CARD="" @@ -187,36 +197,55 @@ else fi if [ -n "$USB_CARD" ]; then - # Set ALSA defaults for the detected USB soundcard log_message "USB soundcard detected." set_alsa_defaults "$USB_CARD" else - # Check for any other non-BCM soundcard (prioritize user-installed cards over onboard ones) OTHER_CARD=$(aplay -l | grep "card" | grep -v -i "$HEADPHONES_CARD_NAME" | grep -v -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$OTHER_CARD" ]; then - # Set ALSA defaults for the user-installed soundcard log_message "User-installed soundcard detected." set_alsa_defaults "$OTHER_CARD" else - # Default to onboard BCM soundcard if no other card is found BCM_CARD=$(aplay -l | grep "card" | grep -i "$HEADPHONES_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$BCM_CARD" ]; then - # Set ALSA defaults for the onboard BCM soundcard log_message "Onboard BCM soundcard detected." set_alsa_defaults "$BCM_CARD" else - # Fall back to HDMI soundcard if no onboard card is found HDMI_CARD=$(aplay -l | grep "card" | grep -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$HDMI_CARD" ]; then - # Set ALSA defaults for the HDMI soundcard log_message "HDMI soundcard detected." set_alsa_defaults "$HDMI_CARD" else - # No suitable soundcard detected, log an error log_message "Error: No suitable soundcard detected." fi fi fi fi +} + +# Main Script +if [ -f /etc/OpenVoiceOS/i2c_platform ]; then + i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform) +else + log_message "/etc/OpenVoiceOS/i2c_platform not found." + i2c_platform="" fi +log_message "$(aplay -l)" # Log detected soundcards + +# Autoconfigure default soundcard +# TODO - possible values not handled (some might be mic input only) +# "SJ201V6" "SJ201V10" "AIYVOICEBONNET", "ADAFRUIT", "RESPEAKER6", "RESPEAKER4" +case "$i2c_platform" in + *WM8960*) + # inform user about possible MK1 arduino boot failure + # we have no way to know, it will just report as WM8960 + log_message "WARNING [Mark1 only]: If this is a Mark 1 device, Arduino may not have booted properly. Power cycle your device until the eyes spin." + setup_wm8960_soundcard + ;; + *MARK1*) + setup_mark1_soundcard + ;; + *) + setup_fallback_soundcard + ;; +esac From 8b74b755e1a4ddc9d424b5bedf014711b036e16c Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:56:12 +0000 Subject: [PATCH 2/6] Update soundcard_autoconfigure Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- soundcard_autoconfigure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soundcard_autoconfigure b/soundcard_autoconfigure index 0b1c132..f9e087f 100644 --- a/soundcard_autoconfigure +++ b/soundcard_autoconfigure @@ -11,7 +11,7 @@ SOUND_SERVER="pipewire" # TODO: Add support for pulseaudio 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 -GOOGLE_VOICEKIT_V1 = "snd_rpi_googlevoicehat" # cant be autodetected by ovos-i2csound , user manually enables it +GOOGLE_VOICEKIT_V1="snd_rpi_googlevoicehat" # cant be autodetected by ovos-i2csound , user manually enables it RESPEAKER_2MIC = "wm8960-soundcard" # Environment variables for PipeWire (or PulseAudio) From bf775d0615cdd603cb96b4803ebf9f976b9dca9c Mon Sep 17 00:00:00 2001 From: miro Date: Sun, 19 Jan 2025 00:57:21 +0000 Subject: [PATCH 3/6] fix --- soundcard_autoconfigure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/soundcard_autoconfigure b/soundcard_autoconfigure index f9e087f..6852752 100644 --- a/soundcard_autoconfigure +++ b/soundcard_autoconfigure @@ -170,7 +170,7 @@ setup_googlevoicekitv1_soundcard() { # just a placeholder, ovos-i2csound will need to grep boot/config.txt to check if overlay is enabled log_message "GoogleVoiceKit soundcard configured by user" if aplay -l | grep "$GOOGLE_VOICEKIT_V1"; then - CARD_NUMBER=$(aplay -l | grep "$MK1_CARD_NAME" | awk '{print $2}' | cut -d':' -f1) + CARD_NUMBER=$(aplay -l | grep "$GOOGLE_VOICEKIT_V1" | awk '{print $2}' | cut -d':' -f1) log_message "Detected CARD_NUMBER for GoogleVoiceKit soundcard: $CARD_NUMBER" set_alsa_defaults "$CARD_NUMBER" else @@ -200,21 +200,28 @@ setup_fallback_soundcard() { log_message "USB soundcard detected." set_alsa_defaults "$USB_CARD" else + # Check for any other non-BCM soundcard (prioritize user-installed cards over onboard ones) OTHER_CARD=$(aplay -l | grep "card" | grep -v -i "$HEADPHONES_CARD_NAME" | grep -v -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$OTHER_CARD" ]; then + # Set ALSA defaults for the user-installed soundcard log_message "User-installed soundcard detected." set_alsa_defaults "$OTHER_CARD" else + # Default to onboard BCM soundcard if no other card is found BCM_CARD=$(aplay -l | grep "card" | grep -i "$HEADPHONES_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$BCM_CARD" ]; then + # Set ALSA defaults for the onboard BCM soundcard log_message "Onboard BCM soundcard detected." set_alsa_defaults "$BCM_CARD" else + # Fall back to HDMI soundcard if no onboard card is found HDMI_CARD=$(aplay -l | grep "card" | grep -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$HDMI_CARD" ]; then + # Set ALSA defaults for the HDMI soundcard log_message "HDMI soundcard detected." set_alsa_defaults "$HDMI_CARD" else + # No suitable soundcard detected, log an error log_message "Error: No suitable soundcard detected." fi fi From 9de09905f8bf49e115a804f9ff65db3a42f1aaa0 Mon Sep 17 00:00:00 2001 From: miro Date: Sun, 19 Jan 2025 00:59:09 +0000 Subject: [PATCH 4/6] diff --- soundcard_autoconfigure | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/soundcard_autoconfigure b/soundcard_autoconfigure index 6852752..122134d 100644 --- a/soundcard_autoconfigure +++ b/soundcard_autoconfigure @@ -141,6 +141,16 @@ get_sink_name_from_card() { sleep 1 +if [ -f /etc/OpenVoiceOS/i2c_platform ]; then + i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform) +else + log_message "/etc/OpenVoiceOS/i2c_platform not found." + i2c_platform="" +fi + +log_message "$(aplay -l)" # Log detected soundcards + + setup_wm8960_soundcard() { log_message "Respeaker-2mic (wm8960) detected by ovos-i2csound." if aplay -l | grep "$RESPEAKER_2MIC"; then @@ -229,16 +239,6 @@ setup_fallback_soundcard() { fi } -# Main Script -if [ -f /etc/OpenVoiceOS/i2c_platform ]; then - i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform) -else - log_message "/etc/OpenVoiceOS/i2c_platform not found." - i2c_platform="" -fi - -log_message "$(aplay -l)" # Log detected soundcards - # Autoconfigure default soundcard # TODO - possible values not handled (some might be mic input only) # "SJ201V6" "SJ201V10" "AIYVOICEBONNET", "ADAFRUIT", "RESPEAKER6", "RESPEAKER4" From 33579ae98883a7d756d74abb258bcb67db28d5cf Mon Sep 17 00:00:00 2001 From: miro Date: Sun, 19 Jan 2025 01:01:59 +0000 Subject: [PATCH 5/6] diff --- soundcard_autoconfigure | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/soundcard_autoconfigure b/soundcard_autoconfigure index 122134d..89affeb 100644 --- a/soundcard_autoconfigure +++ b/soundcard_autoconfigure @@ -140,7 +140,7 @@ get_sink_name_from_card() { # Wait for ovos-i2csound to complete setup sleep 1 - +# Check if the file exists before reading it if [ -f /etc/OpenVoiceOS/i2c_platform ]; then i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform) else @@ -168,6 +168,7 @@ setup_mark1_soundcard() { 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" + # Set ALSA defaults for the detected Mark 1 soundcard set_alsa_defaults "$CARD_NUMBER" else log_message "Error: ovos-i2csound detected Mark 1 but 'aplay -l' could not detect '$MK1_CARD_NAME'" @@ -193,11 +194,13 @@ setup_fallback_soundcard() { # Check for USB soundcard if aplay -l | grep "card" | grep -i "usb"; then USB_CARDS=$(aplay -l | grep "card" | grep -i "usb" | awk '{print $2}' | cut -d':' -f1) + # If multiple USB soundcards are detected, log a warning and pick the last one if [ -n "$USB_CARDS" ]; then CARD_COUNT=$(echo "$USB_CARDS" | wc -l) if [ "$CARD_COUNT" -gt 1 ]; then log_message "Warning: Multiple USB soundcards detected. Using the last detected card." fi + # Select the last USB soundcard detected USB_CARD=$(echo "$USB_CARDS" | tail -n 1) else USB_CARD="" @@ -207,6 +210,7 @@ setup_fallback_soundcard() { fi if [ -n "$USB_CARD" ]; then + # Set ALSA defaults for the detected USB soundcard log_message "USB soundcard detected." set_alsa_defaults "$USB_CARD" else From cb06184469c34ceb550565135eebf3965bdf1a10 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 22 Jan 2025 04:52:15 +0000 Subject: [PATCH 6/6] feat:detect_sound_server (soundcard-autoconfigure) --- ...d_autoconfigure => soundcard-autoconfigure | 195 ++++++++++++------ 1 file changed, 131 insertions(+), 64 deletions(-) rename soundcard_autoconfigure => soundcard-autoconfigure (56%) diff --git a/soundcard_autoconfigure b/soundcard-autoconfigure similarity index 56% rename from soundcard_autoconfigure rename to soundcard-autoconfigure index 89affeb..a229953 100644 --- a/soundcard_autoconfigure +++ b/soundcard-autoconfigure @@ -1,18 +1,38 @@ #!/bin/bash # /usr/libexec/autoconfigure-soundcard # This script automatically configures the default soundcard based on the detected devices. -# Runs after ovos-i2csound and when a USB soundcard is connected/removed. +# It runs after ovos-i2csound and when a USB soundcard is connected or removed. # Constants -OVOS_USER="$(getent passwd 1000 | cut -d: -f1)" -SOUND_SERVER="pipewire" # TODO: Add support for pulseaudio +OVOS_USER="$(getent passwd 1000 | cut -d: -f1)" # Get the username of the first non-system user -# Card names +# Function to detect the active sound server (PipeWire, PulseAudio, or ALSA) +# Returns the sound server type as a string +detect_sound_server() { + # Check if PipeWire is installed + if command -v pipewire > /dev/null; then + echo "pipewire" + # Check if PulseAudio is installed + elif command -v pulseaudio > /dev/null; then + echo "pulse" + # Check if ALSA is available + elif command -v aplay > /dev/null && command -v amixer > /dev/null; then + echo "alsa" + else + echo "No sound server detected" + exit 1 + fi +} + +# Detect the sound server +SOUND_SERVER=$(detect_sound_server) + +# Card names for different soundcards 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 -GOOGLE_VOICEKIT_V1="snd_rpi_googlevoicehat" # cant be autodetected by ovos-i2csound , user manually enables it -RESPEAKER_2MIC = "wm8960-soundcard" +HEADPHONES_CARD_NAME="bcm2835" # Onboard soundcard, not available on RPi 5 +GOOGLE_VOICEKIT_V1="snd_rpi_googlevoicehat" # User manually configures this soundcard +RESPEAKER_2MIC="wm8960-soundcard" # Respeaker 2mic card # Environment variables for PipeWire (or PulseAudio) export PULSE_RUNTIME_PATH="/run/user/1000/pulse/" @@ -22,8 +42,8 @@ export XDG_RUNTIME_DIR="/run/user/1000/" set -euo pipefail # Function to handle errors -# Logs an error message and exits the script. -# Args: +# Logs an error message and exits the script +# Arguments: # $1: Line number where the error occurred # $2: Error code error_handler() { @@ -33,10 +53,11 @@ error_handler() { exit ${error_code} } +# Trap errors and call the error handler trap 'error_handler ${LINENO} $?' ERR -# Function to log messages to the console and a log file -# Args: +# Function to log messages to both console and a log file +# Arguments: # $1: Message to log log_message() { echo "$1" @@ -44,26 +65,50 @@ log_message() { } # Function to check if the script is running as root +# Returns true if running as root, false otherwise is_root() { [ "$(id -u)" -eq 0 ] } -# Function to set ALSA defaults for a given card number -# Updates ~/.asoundrc and sets default pipewire/pulseaudio sink. -# Args: -# $1: The card number to set as default -set_alsa_defaults() { +# ALSA configuration function +# Configures ALSA to use the specified card number as the default +# Arguments: +# $1: Card number +alsa_configure() { local card_number=$1 + log_message "Configuring ALSA at '/home/$OVOS_USER/.asoundrc' with card $card_number" + echo -e "pcm.!default {\n type hw\n card $card_number\n}\nctl.!default {\n type hw\n card $card_number\n}" > "/home/$OVOS_USER/.asoundrc" +} +# PipeWire configuration function +# Configures PipeWire to use the specified card as the default sink +# Arguments: +# $1: Card number +pw_configure() { + local card_number=$1 log_message "Configuring ALSA for PipeWire at '/home/$OVOS_USER/.asoundrc'" echo -e "pcm.!default $SOUND_SERVER\nctl.!default $SOUND_SERVER" > "/home/$OVOS_USER/.asoundrc" + log_message "Match card $card_number to audio sink" + local sink=$(pw_card2sink "$card_number") + log_message "Setting default sink: $sink" + wpctl set-default $sink +} + +# PulseAudio configuration function +# Configures PulseAudio to use the specified card as the default sink +# Arguments: +# $1: Card number +pulse_configure() { + local card_number=$1 + log_message "Configuring ALSA for Pulseaudio at '/home/$OVOS_USER/.asoundrc'" + echo -e "pcm.!default $SOUND_SERVER\nctl.!default $SOUND_SERVER" > "/home/$OVOS_USER/.asoundrc" local sink_name - sink_name=$(get_sink_name_from_card "$card_number") + sink_name=$(pulse_card2sink "$card_number") # If sink name is found, set it as the default using pactl if [ "$sink_name" != "Card index not found" ]; then log_message "Setting default sink to: $sink_name" - # Use pactl to set the default sink for PipeWire (or PulseAudio) + # Use pactl to set the default sink for PulseAudio if is_root; then runuser -u "$OVOS_USER" -- pactl set-default-sink "$sink_name" else @@ -75,31 +120,42 @@ set_alsa_defaults() { fi } -# Function to get the card number associated with a given sink name -# Arguments: -# $1 - Sink name to search for -# Returns: -# The card number associated with the sink name -get_card_from_sink() { - local search="$1" - if is_root; then - runuser -u "$OVOS_USER" -- pactl list sinks | awk -v search="$search" ' - BEGIN {found = 0} - /Name: / { - if (index($2, search) > 0) {found = 1} - else {found = 0} +pw_card2sink() { + local CARD_IDX=$1 + + if [ "$SOUND_SERVER" == "alsa" ]; then + echo "alsa does not support individual sinks" + exit 1 + elif [ "$SOUND_SERVER" == "pulseaudio" ]; then + echo "pulseaudio support not implemented" + exit 1 + elif [ "$SOUND_SERVER" == "pipewire" ]; then + # Extract sink IDs + SINK_IDS=$(wpctl status | awk -v card_idx="$CARD_IDX" ' + /├─ Sinks:/ {capture = 1; next} + /^ ├─|^ └─|^$/ {capture = 0} + capture { + if ($2 == "*") { + gsub(/\.$/, "", $3) + print $3 + } + if ($2 ~ /^[0-9]+\.$/) { + gsub(/\.$/, "", $2) + print $2 + } } - found && /api.alsa.card/ {card=$3} - END {gsub(/"/, "", card); print card}' + ') + + # Loop through each sink ID and inspect it + for SINK in $SINK_IDS; do + CIDX=$(wpctl inspect $SINK | grep -i "api.alsa.pcm.card" | awk -F'"' '{print $2}') + if [ "$CIDX" == "$CARD_IDX" ]; then + echo "$SINK" + fi + done else - pactl list sinks | awk -v search="$search" ' - BEGIN {found = 0} - /Name: / { - if (index($2, search) > 0) {found = 1} - else {found = 0} - } - found && /api.alsa.card/ {card=$3} - END {gsub(/"/, "", card); print card}' + echo "Unsupported sound server: $SOUND_SERVER" + exit 1 fi } @@ -108,7 +164,7 @@ get_card_from_sink() { # $1: The card index to search for # Returns: # The sink name associated with the card index or an error message if not found -get_sink_name_from_card() { +pulse_card2sink() { local card_index="$1" if is_root; then runuser -u "$OVOS_USER" -- pactl list sinks | awk -v card_index="$card_index" ' @@ -137,10 +193,22 @@ get_sink_name_from_card() { fi } +# Function to set up a sound card based on its detected type +# Arguments: +# $1: Card index +setup_card() { + local card_index="$1" + case "$SOUND_SERVER" in + *pipewire*) pw_configure $card_index ;; + *pulse*) pulse_configure $card_index ;; + *) alsa_configure $card_index ;; + esac +} + # Wait for ovos-i2csound to complete setup sleep 1 -# Check if the file exists before reading it +# Read i2c platform configuration from file if [ -f /etc/OpenVoiceOS/i2c_platform ]; then i2c_platform=$(cat /etc/OpenVoiceOS/i2c_platform) else @@ -150,90 +218,89 @@ fi log_message "$(aplay -l)" # Log detected soundcards - +# Function to set up Respeaker 2mic soundcard setup_wm8960_soundcard() { log_message "Respeaker-2mic (wm8960) detected by ovos-i2csound." if aplay -l | grep "$RESPEAKER_2MIC"; then - CARD_NUMBER=$(aplay -l | grep "$RESPEAKER_2MIC" | awk '{print $2}' | cut -d':' -f1) + local CARD_NUMBER=$(aplay -l | grep "$RESPEAKER_2MIC" | awk '{print $2}' | cut -d':' -f1) log_message "Detected CARD_NUMBER for Respeaker-2mic soundcard: $CARD_NUMBER" - set_alsa_defaults "$CARD_NUMBER" + setup_card "$CARD_NUMBER" else log_message "Error: ovos-i2csound detected Respeaker-2mic but 'aplay -l' could not detect '$RESPEAKER_2MIC'" exit 1 fi } +# Function to set up Mark 1 soundcard setup_mark1_soundcard() { log_message "Mark 1 soundcard detected by ovos-i2csound." if aplay -l | grep "$MK1_CARD_NAME"; then - CARD_NUMBER=$(aplay -l | grep "$MK1_CARD_NAME" | awk '{print $2}' | cut -d':' -f1) + local 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" - # Set ALSA defaults for the detected Mark 1 soundcard - set_alsa_defaults "$CARD_NUMBER" + setup_card "$CARD_NUMBER" else log_message "Error: ovos-i2csound detected Mark 1 but 'aplay -l' could not detect '$MK1_CARD_NAME'" exit 1 fi } +# Function to set up GoogleVoiceKit soundcard setup_googlevoicekitv1_soundcard() { # NOTE: special case, not detected by ovos-i2csound (yet) # just a placeholder, ovos-i2csound will need to grep boot/config.txt to check if overlay is enabled log_message "GoogleVoiceKit soundcard configured by user" if aplay -l | grep "$GOOGLE_VOICEKIT_V1"; then - CARD_NUMBER=$(aplay -l | grep "$GOOGLE_VOICEKIT_V1" | awk '{print $2}' | cut -d':' -f1) + local CARD_NUMBER=$(aplay -l | grep "$GOOGLE_VOICEKIT_V1" | awk '{print $2}' | cut -d':' -f1) log_message "Detected CARD_NUMBER for GoogleVoiceKit soundcard: $CARD_NUMBER" - set_alsa_defaults "$CARD_NUMBER" + setup_card "$CARD_NUMBER" else log_message "Error: user configured GoogleVoiceKit but 'aplay -l' could not detect '$GOOGLE_VOICEKIT_V1'" exit 1 fi } +# Function to set up fallback soundcard setup_fallback_soundcard() { + local USB_CARD="" # Check for USB soundcard if aplay -l | grep "card" | grep -i "usb"; then - USB_CARDS=$(aplay -l | grep "card" | grep -i "usb" | awk '{print $2}' | cut -d':' -f1) + local USB_CARDS=$(aplay -l | grep "card" | grep -i "usb" | awk '{print $2}' | cut -d':' -f1) # If multiple USB soundcards are detected, log a warning and pick the last one if [ -n "$USB_CARDS" ]; then - CARD_COUNT=$(echo "$USB_CARDS" | wc -l) + local CARD_COUNT=$(echo "$USB_CARDS" | wc -l) if [ "$CARD_COUNT" -gt 1 ]; then log_message "Warning: Multiple USB soundcards detected. Using the last detected card." fi # Select the last USB soundcard detected USB_CARD=$(echo "$USB_CARDS" | tail -n 1) - else - USB_CARD="" fi - else - USB_CARD="" fi if [ -n "$USB_CARD" ]; then # Set ALSA defaults for the detected USB soundcard log_message "USB soundcard detected." - set_alsa_defaults "$USB_CARD" + setup_card "$USB_CARD" else # Check for any other non-BCM soundcard (prioritize user-installed cards over onboard ones) - OTHER_CARD=$(aplay -l | grep "card" | grep -v -i "$HEADPHONES_CARD_NAME" | grep -v -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) + local OTHER_CARD=$(aplay -l | grep "card" | grep -v -i "$HEADPHONES_CARD_NAME" | grep -v -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$OTHER_CARD" ]; then # Set ALSA defaults for the user-installed soundcard log_message "User-installed soundcard detected." - set_alsa_defaults "$OTHER_CARD" + setup_card "$OTHER_CARD" else # Default to onboard BCM soundcard if no other card is found - BCM_CARD=$(aplay -l | grep "card" | grep -i "$HEADPHONES_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) + local BCM_CARD=$(aplay -l | grep "card" | grep -i "$HEADPHONES_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$BCM_CARD" ]; then # Set ALSA defaults for the onboard BCM soundcard log_message "Onboard BCM soundcard detected." - set_alsa_defaults "$BCM_CARD" + setup_card "$BCM_CARD" else # Fall back to HDMI soundcard if no onboard card is found - HDMI_CARD=$(aplay -l | grep "card" | grep -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) + local HDMI_CARD=$(aplay -l | grep "card" | grep -i "$HDMI_CARD_NAME" | awk '{print $2}' | cut -d':' -f1 | head -n 1) if [ -n "$HDMI_CARD" ]; then # Set ALSA defaults for the HDMI soundcard log_message "HDMI soundcard detected." - set_alsa_defaults "$HDMI_CARD" + setup_card "$HDMI_CARD" else # No suitable soundcard detected, log an error log_message "Error: No suitable soundcard detected."