Pi 5: alsamixer displaying different controls on boot

I have a Raspberry Pi 5 4Gb. I am trying to run a Python script on boot which will allow me to control the volume of my default amixer device (Master) through a slider switch. The script works perfectly fine when I run it manually. However, I am unable to access the “Master” device via amixer when running the script on boot.

When I run the “amixer controls” command via ssh while logged into user pi (or running the Python script), I get this output:

numid=4,iface=MIXER,name='Master Playback Switch'
numid=3,iface=MIXER,name='Master Playback Volume'
numid=2,iface=MIXER,name='Capture Switch'
numid=1,iface=MIXER,name='Capture Volume'

However, when I run the same script on reboot, I get this output instead:

numid=1,iface=CARD,name='HDMI Jack'
numid=5,iface=PCM,name='ELD'
numid=4,iface=PCM,name='IEC958 Playback Default'
numid=3,iface=PCM,name='IEC958 Playback Mask'
numid=2,iface=PCM,name='Playback Channel Map'

Note that I get this same second output if I run the command “sudo amixer controls”.

I’ve tried running the script via crontab -e and I’ve also tried putting this line into my rc.local file:

su -u pi -c "python /home/pi/scripts/volume.py > /home/pi/scripts/volume.log 2>&1" &

However, both of these result in the same second output.

I believe getting the first output has something to do with running the script under the correct user or setting my environment variables correctly, but I have no idea how to do it. Would someone be able to help me here? Thanks!

2 Likes

Hey @Thimis, welcome to the forums!

From my understanding of how scripts run on boot when placed in the rc.local file, the script will run as soon as it can, often before other system processes have properly started up.

I would suggest running this script on boot using a systemd service. You can find instructions on how to do this in the guide on this RPi forum thread

https://forums.raspberrypi.com/viewtopic.php?t=314455

Section 4.4 Using A Systemd Service, should run you through the basics of this method.

Hope this helps!

1 Like

Thanks for your response Samuel. I will try this out in a few days when I have the time to do so.

2 Likes

Hi Samuel,

Finally had the chance to try this out. Using that guide did not work, regardless of which method I used. That being said, I tried reinstalling the OS as per a different suggestion and that did the trick. This fixed the core issue which was the difference in controls between pi and su (running the command with and without sudo should display the same controls). I really hope there’s a better way of fixing this issue for anyone who may encounter this in the future, but reinstalling the OS seems like a foolproof way of fixing it for anyone who has the time.

1 Like

Hey @Thimis,

Thanks for keeping us updated! I’m glad reinstalling the OS worked, although it is a bit of an involved solution.

Are you aware of any differences in your OS installation before and after this reinstall like a version change or anything that we could point to as a possible cause of this problem?

The difference here is most likely because of pipewire. It runs as a systemd user service, starting when you log in with a regular user account, and takes over as the default audio “device” for login sessions for that user. I assume that when you reinstalled the OS you installed the lite version instead of full, because that doesn’t have pipewire installed by default last time I checked?

The “correct” way to run your script at boot in a way that works with pipewire involves a couple of extra steps:

  • install your script as a systemd user service - put your .service file in ~/.config/systemd/user/, and enable it with systemctl --user enable <servicename>
  • enable lingering to make the user services run at startup - loginctl enable-linger pi

Alternatively, just ignore all the pipewire stuff and use alsa directly. Pipewire makes some things a lot easier but for basic setups it can almost be more effort than you need.

Hope this helps!

2 Likes