Alsa-restore is driving me crazy

I’m trying to understand why alsamixer’s playback volume is not restored after reboot.

From my understanding, it should be done by alsa-restore.service

Basically this service launches alsactl store when shutting down the computer and alsactl restore when starting. I also tested and those commands work perfectly fine when launched as super user. They use the default file /var/lib/alsa/asound.state and I tested both directions by testing the file is modified by storing and that manually modifying the file before restoring works.
I also tested that the service is executed and, according to journalctl, it is.

So far so good.

However, the “Headphone Playback Volume” is always reset to 0 after rebooting.

I modified the service to debug, here is the content:

#
# Note that two different ALSA card state management schemes exist and they
# can be switched using a file exist check - /etc/alsa/state-daemon.conf .
#

[Unit]
Description=Save/Restore Sound Card State
ConditionPathExists=!/etc/alsa/state-daemon.conf
ConditionPathExistsGlob=/dev/snd/control*
ConditionPathExists=/var/lib/alsa/asound.state

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=head -n30 /var/lib/alsa/asound.state
ExecStart=/usr/bin/alsactl -d restore -f /var/lib/alsa/asound.state
#ExecStop=/usr/bin/alsactl store

Here is the log:

-- Logs begin at Fri 2020-09-04 14:44:24 CEST, end at Sat 2020-09-19 16:03:01 CEST. --
Sep 19 15:57:48 pbp systemd[1]: Starting Save/Restore Sound Card State...
Sep 19 15:57:48 pbp head[761]: state.rockchipes8316c {
Sep 19 15:57:48 pbp head[761]:         control.1 {
Sep 19 15:57:48 pbp head[761]:                 iface CARD
Sep 19 15:57:48 pbp head[761]:                 name 'Headphones Jack'
Sep 19 15:57:48 pbp head[761]:                 value false
Sep 19 15:57:48 pbp head[761]:                 comment {
Sep 19 15:57:48 pbp head[761]:                         access read
Sep 19 15:57:48 pbp head[761]:                         type BOOLEAN
Sep 19 15:57:48 pbp head[761]:                         count 1
Sep 19 15:57:48 pbp head[761]:                 }
Sep 19 15:57:48 pbp head[761]:         }
Sep 19 15:57:48 pbp head[761]:         control.2 {
Sep 19 15:57:48 pbp head[761]:                 iface MIXER
Sep 19 15:57:48 pbp head[761]:                 name 'Headphone Playback Volume'
Sep 19 15:57:48 pbp head[761]:                 value.0 3
Sep 19 15:57:48 pbp head[761]:                 value.1 3
Sep 19 15:57:48 pbp head[761]:                 comment {
Sep 19 15:57:48 pbp head[761]:                         access 'read write'
Sep 19 15:57:48 pbp head[761]:                         type INTEGER
Sep 19 15:57:48 pbp head[761]:                         count 2
Sep 19 15:57:48 pbp head[761]:                         range '0 - 3'
Sep 19 15:57:48 pbp head[761]:                         dbmin -4800
Sep 19 15:57:48 pbp head[761]:                         dbmax 0
Sep 19 15:57:48 pbp head[761]:                         dbvalue.0 0
Sep 19 15:57:48 pbp head[761]:                         dbvalue.1 0
Sep 19 15:57:48 pbp head[761]:                 }
Sep 19 15:57:48 pbp head[761]:         }
Sep 19 15:57:48 pbp head[761]:         control.3 {
Sep 19 15:57:48 pbp head[761]:                 iface MIXER
Sep 19 15:57:48 pbp head[761]:                 name 'Headphone Mixer Volume'
Sep 19 15:57:48 pbp systemd[1]: Finished Save/Restore Sound Card State.

Here you can see that the value is 3 as intended.
I also tested that the command successfully executes, at some point I added a command to store the state and display it and the value was 3. However at startup the value is 0. If I launch sudo alsactl restore it will be set up to 3 but I don’t want to launch this at each startup.

I also wanted to make sure that alsactl is not called after this, so I replaced /usr/bin/alsactl with a script that logs every call (alsactl.save is the original command):

#!/bin/bash

date >> /home/louisabraham/alsactl.log
whoami >> /home/louisabraham/alsactl.log
echo "$@" >> /home/louisabraham/alsactl.log
echo >> /home/louisabraham/alsactl.log

head /var/lib/alsa/asound.state -n20 >>  /home/louisabraham/alsactl.log

echo >> /home/louisabraham/alsactl.log

/usr/bin/alsactl.save -d "$@" 2>> /home/louisabraham/alsactl.log

echo >> /home/louisabraham/alsactl.log

The output is the following:

Sat Sep 19 16:43:27 CEST 2020
root
restore 0

state.rockchipes8316c {
        control.1 {
                iface CARD
                name 'Headphones Jack'
                value false
                comment {
                        access read
                        type BOOLEAN
                        count 1
                }
        }
        control.2 {
                iface MIXER
                name 'Headphone Playback Volume'
                value.0 3
                value.1 3
                comment {
                        access 'read write'
                        type INTEGER
                        count 2

/usr/bin/alsactl.save: set_controls:1479: device='hw:0', doit=0
/usr/bin/alsactl.save: set_controls:1491: card-info-id: 'rockchipes8316c'
/usr/bin/alsactl.save: set_controls:1517: maxnumid=37
/usr/bin/alsactl.save: set_controls:1535: result code: 0
/usr/bin/alsactl.save: set_controls:1479: device='hw:0', doit=1
/usr/bin/alsactl.save: set_controls:1491: card-info-id: 'rockchipes8316c'
/usr/bin/alsactl.save: set_controls:1517: maxnumid=37
/usr/bin/alsactl.save: set_controls:1535: result code: 0

Sat Sep 19 04:45:07 PM CEST 2020
root
-d restore -f /var/lib/alsa/asound.state

state.rockchipes8316c {
        control.1 {
                iface CARD
                name 'Headphones Jack'
                value false
                comment {
                        access read
                        type BOOLEAN
                        count 1
                }
        }
        control.2 {
                iface MIXER
                name 'Headphone Playback Volume'
                value.0 3
                value.1 3
                comment {
                        access 'read write'
                        type INTEGER
                        count 2

/usr/bin/alsactl.save: set_controls:1479: device='hw:0', doit=0
/usr/bin/alsactl.save: set_controls:1491: card-info-id: 'rockchipes8316c'
/usr/bin/alsactl.save: set_controls:1517: maxnumid=37
/usr/bin/alsactl.save: set_controls:1535: result code: 0
/usr/bin/alsactl.save: set_controls:1479: device='hw:0', doit=1
/usr/bin/alsactl.save: set_controls:1491: card-info-id: 'rockchipes8316c'
/usr/bin/alsactl.save: set_controls:1517: maxnumid=37
/usr/bin/alsactl.save: set_controls:1535: result code: 0

Apparently, alsactl restore 0 is called (I don’t know why) then alsactl restore is called by the service and not called after that. I have spent hour trying to solve this (eg with autostart scripts) but nothing worked and I’m totally lost!

1 Like

A friend advised me not to lose more time on such a trivial issue. Pulseaudio is probably the culprit.

My current config is the following and just works:

[louisabraham@pbp ~]$ cat /usr/lib/systemd/system/alsa-restore.service 
#
# Note that two different ALSA card state management schemes exist and they
# can be switched using a file exist check - /etc/alsa/state-daemon.conf .
#

[Unit]
Description=Save/Restore Sound Card State
ConditionPathExists=!/etc/alsa/state-daemon.conf
ConditionPathExistsGlob=/dev/snd/control*
ConditionPathExists=/var/lib/alsa/asound.state

[Service]
Type=oneshot
RemainAfterExit=true
# ExecStart=/usr/bin/alsactl -d restore -f /var/lib/alsa/asound.state
ExecStop=/usr/bin/alsactl store -f /home/louisabraham/.asound.state
[louisabraham@pbp ~]$ cat .config/autostart-scripts/alsactl-restore.sh 
#! /usr/bin/sh

sleep 10 && alsactl --file ~/.asound.state restore
1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.