This is an old problem that regularly re-surface, most recently after an upgrade to the latest kernel and firmware, for Raspian Stretch, 4.14.30-v7+
.
It seem that it may have something to do with both how Raspberry Pi's are using the systemd services when boot and shutting down and how the ALSA daemons and services have been setup initially (or after system upgrade). My best guess is that the post install scripts for something is not recognizing that you already have an /home/pi/.asoundrc
file and then tries to restore it to some default. It is unclear from where this default is coming from. Certainly not what's written in the comments of the many ALSA or system services config files or related man pages. But it seem to be coming from a bug in the lxpanels volume applet.
In my case, the following seem to have resolved the issue:
- First remove the Volume Applet from the lxpanel, then:
# Make sure your .asoundrc is correct, then do:
alsactl kill save_and_quit
sudo shutdown now
PS. It also seem important to use shutdown, and not reboot!
Debugging attempts
If the above doesn't work, then read this.
As a side, there seem to be a bug in how systemctl is handling services. The FS in the pi is different (by missing parts) from other Debian based systems, so where the service scripts are located and handled is not fully according its own man pages.
To see the relevant ALSA related services, do:
sudo systemctl status alsa-restore alsa-state
Under normal circumstances you should be able to shutdown the suspected static services by something like:
sudo systemctl mask --system alsa-state.service --now
sudo systemctl mask --system alsa-restore.service --now
However, the runtime locations of [system,user,runtime, global]
which are:
/etc/systemd/system-preset/*.preset
/run/systemd/system-preset/*.preset
/lib/systemd/system-preset/*.preset
/etc/systemd/user-preset/*.preset
/run/systemd/user-preset/*.preset
/usr/lib/systemd/user-preset/*.preset
are not respected as described in man systemd.preset
.
To see all services and their current state, use:
systemctl list-unit-files -t service -all
You can also the reverse dependencies with:
systemctl list-dependencies --reverse alsa-restore.service
alsa-restore.service
● └─basic.target
● └─multi-user.target
● └─graphical.target
In any case, when disabling the service with mask
, it should replace the file with a symlink to /dev/null
, only that this doesn't happen in the right place (according to above). So instead we have to remove the file manually (backup it before) and then create the link.
cp /etc/systemd/system/alsa-restore.service ~/alsa-restore_service.bak
cd /etc/systemd/system/
sudo rm alsa-restore.service
sudo ln -s /dev/null alsa-restore.service
# It should look something like:
ls -al /lib/systemd/system |grep alsa
lrwxrwxrwx 1 root root 9 Apr 25 13:23 alsa-restore.service -> /dev/null
lrwxrwxrwx 1 root root 9 Apr 25 13:26 alsa-state.service -> /dev/null
lrwxrwxrwx 1 root root 9 Jan 23 2017 alsa-utils.service -> /dev/null
Now make sure to repeat the above also for alsa-state.service
,and the same files in the directory: /lib/systemd/system/
if not already there.
DISCLAIMER
The above is most likely not the correct way to do this, so please regard this as a very experimental work-around until that buggy beahviour has been resolved. It may very likely break your ALSA functionality altogether.
pcm.!default
andctl.!default
don't have card 2 but card 0. – timothylhuillier Aug 30 '16 at 20:53