Rhasspy with respeaker 2 hat starts with highest playback volume

I noticed that after rebooting my raspberry with the respeaker-2 hat, it always starts with the highest possible playback volume. So if I speak out the wake-word, I get a beep which is extremely loud. I then always have to go to the sound settings of the raspberry to reduce the volume to say 50%. Does someone know here how to set the initial volume to a decent value? Maybe a startup script?
You can see here below what the initial settings of the sound card are:
https://www.dropbox.com/s/k645ehdbgw7s5rt/audiosettingsafterreboot.png?dl=1

kind regards,
hugo

Coincidentally I also noticed this today after rebooting my Rhasspy satellite. I had to dive into some of the Seeed driver files, but it turns out that the seeed-voicecard.service systemd script removes your system’s asound.conf and asound.state at each boot, replacing them by its default files.

If you know this and read the /usr/bin/seeed-voicecard script, the solution for the state file (containing your volume settings) is simple: let the ALSA service store to and restore from this file from the Seeed driver. Have a look at the alsa-restore.service file:

$ systemctl cat alsa-restore.service
# /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
Documentation=man:alsactl(1)
ConditionPathExists=!/etc/alsa/state-daemon.conf
ConditionPathExistsGlob=/dev/snd/control*
After=alsa-state.service

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=-/usr/sbin/alsactl -E HOME=/run/alsa restore
ExecStop=-/usr/sbin/alsactl -E HOME=/run/alsa store

You need to change the latter two lines. So edit the service file to override these lines:

sudo systemctl edit alsa-restore.service

Then add the following lines containing the filename of the Seeed driver’s asound state file:

[Service]
ExecStart=
ExecStart=-/usr/sbin/alsactl -E HOME=/run/alsa -f /etc/voicecard/wm8960_asound.state restore
ExecStop=
ExecStop=-/usr/sbin/alsactl -E HOME=/run/alsa -f /etc/voicecard/wm8960_asound.state store

Reload the systemd configuration:

sudo systemctl daemon-reload

Then reboot. After this, every change you make to the ALSA mixer (for instance with the alsamixer command) will be saved when your Raspberry Pi shuts down and reloaded when it boots, so it uses the volume you have set.

1 Like

There should be no need to actually edit the files, the github has this easily overlooked line that tells how to save the current settings for the future:

If you want to change the alsa settings, You can use sudo alsactl - file=/etc/voicecard/ac108_asound.state store to save it.

I copied that line from the 4mic part of the readme, but it is in the 2mic part also. They could have made it more obvious thought.

2 Likes

I missed that indeed! Of course you have to make sure then you don’t forget to store your state after each change.

1 Like

sudo alsactl store will just do all cards in one to whatever settings.

Also if you don’t like the wierd and wonderful respeaker drivers.

Just do a amixer contents and copy as there are far to many to get right from a blank install.

I don’t get it right:

sudo alsactl - file=/etc/voicecard/ac108_asound.state store
pi@rhasspy:~ $ alsactl: Unknown command ‘-’…
bash: alsactl:: command not found

Should be:

sudo alsactl --file=/etc/voicecard/ac108_asound.state store

or:

sudo alsactl -f /etc/voicecard/ac108_asound.state store

And in your case with the ReSpeaker 2-Mic HAT the file should be /etc/voicecard/wm8960_asound.state.

1 Like

Would you mind elaborating a bit more? Thx!

1 Like

Thanks for the extra information (the syntax of the original posted command made no sense to me).
For which audio hat is the command?:

sudo alsactl -f /etc/voicecard/ac108_asound.state store

This could be useful for future forum readers

kind regards,
hugo

That’s for the 4-Mic Array, you can see the command at the bottom of this section in the GitHub repository’s README file.

Yeah there are a lot of settings to get right and many of the toggles like all cards can not be set in alsamixer.

amixer pi@raspberrypi:~ $ amixer -c2 contents
numid=12,iface=MIXER,name='Headphone Playback ZC Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=off,off
numid=11,iface=MIXER,name='Headphone Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
  : values=110,110
  | dBscale-min=-121.00dB,step=1.00dB,mute=1
numid=17,iface=MIXER,name='PCM Playback -6dB Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=57,iface=MIXER,name='Mono Output Mixer Left Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=58,iface=MIXER,name='Mono Output Mixer Right Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=41,iface=MIXER,name='ADC Data Output Select'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'Left Data = Left ADC;  Right Data = Right ADC'
  ; Item #1 'Left Data = Left ADC;  Right Data = Left ADC'
  ; Item #2 'Left Data = Right ADC; Right Data = Right ADC'
  ; Item #3 'Left Data = Right ADC; Right Data = Left ADC'
  : values=0
numid=19,iface=MIXER,name='ADC High Pass Filter Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=36,iface=MIXER,name='ADC PCM Capture Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=255,step=0
  : values=195,195
  | dBscale-min=-97.50dB,step=0.50dB,mute=1
numid=18,iface=MIXER,name='ADC Polarity'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'No Inversion'
  ; Item #1 'Left Inverted'
  ; Item #2 'Right Inverted'
  ; Item #3 'Stereo Inversion'
  : values=0
numid=2,iface=MIXER,name='Capture Volume ZC Switch'
  ; type=INTEGER,access=rw------,values=2,min=0,max=1,step=0
  : values=0,0
numid=3,iface=MIXER,name='Capture Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=1,iface=MIXER,name='Capture Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=63,step=0
  : values=43,43
  | dBscale-min=-17.25dB,step=0.75dB,mute=0
numid=10,iface=MIXER,name='Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=255,step=0
  : values=246,246
  | dBscale-min=-127.50dB,step=0.50dB,mute=1
numid=23,iface=MIXER,name='3D Filter Lower Cut-Off'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'Low'
  ; Item #1 'High'
  : values=0
numid=22,iface=MIXER,name='3D Filter Upper Cut-Off'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'High'
  ; Item #1 'Low'
  : values=0
numid=25,iface=MIXER,name='3D Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=24,iface=MIXER,name='3D Volume'
  ; type=INTEGER,access=rw------,values=1,min=0,max=15,step=0
  : values=0
numid=33,iface=MIXER,name='ALC Attack'
  ; type=INTEGER,access=rw------,values=1,min=0,max=15,step=0
  : values=2
numid=32,iface=MIXER,name='ALC Decay'
  ; type=INTEGER,access=rw------,values=1,min=0,max=15,step=0
  : values=3
numid=26,iface=MIXER,name='ALC Function'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'Off'
  ; Item #1 'Right'
  ; Item #2 'Left'
  ; Item #3 'Stereo'
  : values=0
numid=30,iface=MIXER,name='ALC Hold Time'
  ; type=INTEGER,access=rw------,values=1,min=0,max=15,step=0
  : values=0
numid=27,iface=MIXER,name='ALC Max Gain'
  ; type=INTEGER,access=rw------,values=1,min=0,max=7,step=0
  : values=7
numid=29,iface=MIXER,name='ALC Min Gain'
  ; type=INTEGER,access=rw------,values=1,min=0,max=7,step=0
  : values=0
numid=31,iface=MIXER,name='ALC Mode'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'ALC'
  ; Item #1 'Limiter'
  : values=0
numid=28,iface=MIXER,name='ALC Target'
  ; type=INTEGER,access=rw------,values=1,min=0,max=15,step=0
  : values=4
numid=21,iface=MIXER,name='DAC Deemphasis Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=42,iface=MIXER,name='DAC Mono Mix'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'Stereo'
  ; Item #1 'Mono'
  : values=0
numid=20,iface=MIXER,name='DAC Polarity'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'No Inversion'
  ; Item #1 'Left Inverted'
  ; Item #2 'Right Inverted'
  ; Item #3 'Stereo Inversion'
  : values=0
numid=45,iface=MIXER,name='Left Boost Mixer LINPUT1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=43,iface=MIXER,name='Left Boost Mixer LINPUT2 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=44,iface=MIXER,name='Left Boost Mixer LINPUT3 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=9,iface=MIXER,name='Left Input Boost Mixer LINPUT1 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=3,step=0
  : values=3
  | dBrange-
    rangemin=0,,rangemax=1
      | dBscale-min=0.00dB,step=13.00dB,mute=0
    rangemin=2,,rangemax=3
      | dBscale-min=20.00dB,step=9.00dB,mute=0

numid=5,iface=MIXER,name='Left Input Boost Mixer LINPUT2 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=0
  | dBscale-min=-15.00dB,step=3.00dB,mute=1
numid=4,iface=MIXER,name='Left Input Boost Mixer LINPUT3 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=0
  | dBscale-min=-15.00dB,step=3.00dB,mute=1
numid=49,iface=MIXER,name='Left Input Mixer Boost Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=53,iface=MIXER,name='Left Output Mixer Boost Bypass Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=37,iface=MIXER,name='Left Output Mixer Boost Bypass Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=0
  | dBscale-min=-21.00dB,step=3.00dB,mute=0
numid=52,iface=MIXER,name='Left Output Mixer LINPUT3 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=38,iface=MIXER,name='Left Output Mixer LINPUT3 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=0
  | dBscale-min=-21.00dB,step=3.00dB,mute=0
numid=51,iface=MIXER,name='Left Output Mixer PCM Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=35,iface=MIXER,name='Noise Gate Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=34,iface=MIXER,name='Noise Gate Threshold'
  ; type=INTEGER,access=rw------,values=1,min=0,max=31,step=0
  : values=0
numid=48,iface=MIXER,name='Right Boost Mixer RINPUT1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=46,iface=MIXER,name='Right Boost Mixer RINPUT2 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=47,iface=MIXER,name='Right Boost Mixer RINPUT3 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=8,iface=MIXER,name='Right Input Boost Mixer RINPUT1 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=3,step=0
  : values=3
  | dBrange-
    rangemin=0,,rangemax=1
      | dBscale-min=0.00dB,step=13.00dB,mute=0
    rangemin=2,,rangemax=3
      | dBscale-min=20.00dB,step=9.00dB,mute=0

numid=7,iface=MIXER,name='Right Input Boost Mixer RINPUT2 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=0
  | dBscale-min=-15.00dB,step=3.00dB,mute=1
numid=6,iface=MIXER,name='Right Input Boost Mixer RINPUT3 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=0
  | dBscale-min=-15.00dB,step=3.00dB,mute=1
numid=50,iface=MIXER,name='Right Input Mixer Boost Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=56,iface=MIXER,name='Right Output Mixer Boost Bypass Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=39,iface=MIXER,name='Right Output Mixer Boost Bypass Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=5
  | dBscale-min=-21.00dB,step=3.00dB,mute=0
numid=54,iface=MIXER,name='Right Output Mixer PCM Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=55,iface=MIXER,name='Right Output Mixer RINPUT3 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=40,iface=MIXER,name='Right Output Mixer RINPUT3 Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=7,step=0
  : values=2
  | dBscale-min=-21.00dB,step=3.00dB,mute=0
numid=16,iface=MIXER,name='Speaker AC Volume'
  ; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0
  : values=5
numid=15,iface=MIXER,name='Speaker DC Volume'
  ; type=INTEGER,access=rw------,values=1,min=0,max=5,step=0
  : values=4
numid=13,iface=MIXER,name='Speaker Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
  : values=127,127
  | dBscale-min=-121.00dB,step=1.00dB,mute=1
numid=14,iface=MIXER,name='Speaker Playback ZC Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=off,off
1 Like

Copy this or parts of it to which file exactly?

kind regards,
hugo

koan wrote:

sudo alsactl --file=/etc/voicecard/ac108_asound.state store

or:

sudo alsactl -f /etc/voicecard/ac108_asound.state store

And in your case with the ReSpeaker 2-Mic HAT the file should be /etc/voicecard/wm8960_asound.state .

Thanks, works like a charm!
hugo