Thank you for your donation!


Cloudsmith graciously provides open-source package management and distribution for our project.


Idea: Keep Last Selected Audio Output Device After Reboot
#11
(03-14-2025, 09:00 PM)Tim Curtis Wrote: Upcoming 9.2.7 already has a fix for this issue.

Do you want to try the test file?

Ok
Thank you for the update!
Reply
#12
This would be great! PI is connected via USB to my amp/dac. I power-on my PI and amp/dav via remote controlled sockets, but the amp/dac goes first in standby instead of powering on. When moOde comes up, and I'm not fast enough to switch on my amp, it doesnt't find the dac and tries HDMI, requiring manually setting in moOde the audio output to my dac, when the amp is powerd-on.
Reply
#13
Information 
This is the my solution I'm trying, but I'm not sure if it's stable.

1. Device Detection
> script:
sudo nano /usr/local/bin/detect_alsa_device.sh
Code:
#!/bin/bash

LAST_DEVICE_FILE="/var/local/last-alsa-device"

echo "Starting ALSA device detector..."
# Check if the stored device file exists
if [ ! -f "$LAST_DEVICE_FILE" ]; then
   echo "No last ALSA device record found. Skipping..."
   exit 0
fi
# Read the last stored ALSA device information from the file
LAST_FILE_ROW1=$(head -n 1 "$LAST_DEVICE_FILE")
LAST_FILE_ROW2=$(head -n 2 "$LAST_DEVICE_FILE" | tail -n 1)
LAST_FILE_ROW3=$(head -n 3 "$LAST_DEVICE_FILE" | tail -n 1)
LAST_FILE_ROW4=$(head -n 4 "$LAST_DEVICE_FILE" | tail -n 1)
# Extract stored values
LAST_CARD=$(echo "$LAST_FILE_ROW1" | awk '{gsub(":", "", $2); print $2}')
LAST_DEVICE=$(echo "$LAST_FILE_ROW1" | cut -d' ' -f3-)
LAST_OUTPUT_MODE="$LAST_FILE_ROW2"
LAST_VOLUME_MAX="$LAST_FILE_ROW3"
LAST_MIXER_TYPE="$LAST_FILE_ROW4"
# Pooling
while true; do
   # Detect the current ALSA device
   CURRENT_CARD=$(aplay -l | grep "$LAST_DEVICE" | awk -F'[: ]+' '{print $2}')
   # If the device is not found, continue the loop
   if [[ -z "$CURRENT_CARD" ]]; then
       echo "Last ALSA device ($LAST_DEVICE) not found in aplay -l. Skipping..."
       sleep 3
       continue
   fi

   CURRENT_DEVICE="$LAST_DEVICE"
   echo "Last ALSA: card $LAST_CARD ($LAST_DEVICE)"
   echo "Current ALSA: card $CURRENT_CARD ($CURRENT_DEVICE)"
   # Get the currently stored ALSA device in Moode
   CFG_MPD_CARD=$(moodeutl -q "SELECT value FROM cfg_mpd WHERE param='device';" | awk -F'|' '{print $1}')
   if [ "$CFG_MPD_CARD" != "$LAST_CARD" ]; then
       echo "Updating Moode to use last known ALSA device ($LAST_CARD : $LAST_DEVICE) | $LAST_OUTPUT_MODE | $LAST_VOLUME_MAX | $LAST_MIXER_TYPE ..."
       sleep 1
       moodeutl -q "UPDATE cfg_mpd SET value='$LAST_CARD' WHERE param='device'; \
       UPDATE cfg_system SET value='$LAST_DEVICE' WHERE param='adevname'; \
       UPDATE cfg_system SET value='$LAST_CARD' WHERE param='cardnum'; \
       UPDATE cfg_system SET value='$LAST_OUTPUT_MODE' WHERE param='alsa_output_mode'; \
       UPDATE cfg_system SET value='$LAST_VOLUME_MAX' WHERE param='alsavolume_max'; \
       UPDATE cfg_mpd SET value='$LAST_MIXER_TYPE' WHERE param='mixer_type';"

        echo "Cleaning \$_SESSION variables..."
        moodeutl -D cardnum
        moodeutl -D adevname
        moodeutl -D alsa_output_mode
        moodeutl -D alsavolume_max
        moodeutl -D amixname
       break
   fi
   sleep 5
done

sleep 1
# Restart Moode services as the www-data user
if ! pgrep -f "moodeutl -r" > /dev/null; then
   echo "Restarting Moode servers..."
   /bin/su -s /bin/bash -c "moodeutl -r" www-data
else
   echo "Moode server is already being restarted. Skipping..."
fi
> systemd Service:
sudo nano /etc/systemd/system/detect_alsa_device.service
Code:
[Unit]
Description=Detect ALSA device and restore last known output
After=sound.target network.target
Requires=sound.target

[Service]
ExecStart=/usr/local/bin/detect_alsa_device.sh
Restart=on-failure
RestartSec=5
User=root
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

[Install]
WantedBy=multi-user.target

2. Device Monitoring
> script:
sudo nano /usr/local/bin/monitor_alsa_device.sh
Code:
#!/bin/bash

WATCH_DIR="/etc/alsa/conf.d/"
LAST_DEVICE_FILE="/var/local/last-alsa-device"

echo "Starting ALSA device monitor..." | systemd-cat -t monitor_alsa_device

inotifywait -m -e moved_to,delete_self,modify "$WATCH_DIR" | while read path action file; do
    if [ "$file" == "_audioout.conf" ]; then
        echo "Detected change in _audioout.conf ($action)"

        CURRENT_CARD=$(moodeutl --hwparams | grep "card" | awk -F'[: ]+' '{print $2}')
        CURRENT_DEVICE=$(moodeutl --hwparams | grep "card" | cut -d' ' -f3-)

        if [[ "$CURRENT_CARD" == "empty" ]]; then
            echo "ALSA device not initialized yet. Skipping update."
            continue
        fi
        echo "Temporarily stopping detect_alsa_device.service"
        systemctl stop detect_alsa_device.service
        sleep 1
        FORMATTED_ENTRY="card $CURRENT_CARD: $CURRENT_DEVICE"

        echo "Recording last ALSA device: $FORMATTED_ENTRY"
        echo "$FORMATTED_ENTRY" > "$LAST_DEVICE_FILE"
        moodeutl -q "SELECT value FROM cfg_system WHERE param='alsa_output_mode'" >> "$LAST_DEVICE_FILE"
        moodeutl -q "SELECT value FROM cfg_system WHERE param='alsavolume_max'" >> "$LAST_DEVICE_FILE"
        moodeutl -q "SELECT value FROM cfg_mpd WHERE param='mixer_type'" >> "$LAST_DEVICE_FILE"
    fi
done
> systemd Service:
sudo nano /etc/systemd/system/monitor_alsa_device.service
Code:
[Unit]
Description=Monitor ALSA device changes for Moode
After=sound.target network.target
Requires=sound.target

[Service]
ExecStart=/usr/local/bin/monitor_alsa_device.sh
Restart=on-failure
RestartSec=5s
User=root

[Install]
WantedBy=multi-user.target

Any insights or suggestions would be greatly appreciated.

Thanks!
Reply
#14
(03-14-2025, 09:00 PM)Tim Curtis Wrote: Upcoming 9.2.7 already has a fix for this issue.

Do you want to try the test file?

Great.  I have 3 Pis connected to a usb dac with a usb switch.  I do a lot of audio out configuration.  Since many times I'm using BubbleUPNP to stream Qobuz it means I have to do a bit of work.  Hope this will take care of the situation where the dac is disconnected then reconnected.  

This setup does raise the question:  Why have 3 separate Moode installations sharing the same usb dac?  I plead diminished capacity.
Reply
#15
...diminished capacity?

Bzzt - wrong answer.

Surely, the correct answer is "because I can" Big Grin

Regards,
Kent
Reply


Forum Jump: