Discussion:
[pulseaudio-discuss] Change sound via acpid
John W
2015-12-23 05:39:57 UTC
Permalink
Hello,

I'm trying to make the mute/unmute key on my laptop work.
It generates acpi events, but does not generate XF86AudioMute X11
message - In fact, I prefer it to be that way, since I don't want to
rely upon X11 running in order to do this.

I'm trying to figure out the "right" way to do this.
N.B.: It is my understanding that running in system mode, while it may
work, is not the "right" way to do this. I am looking for an
alternative to that, if possible.

My acpi script runs (as root), and I want it to toggle the mute state.

I tried "amixer set Master toggle", but that doesn't work as root.
I can reproduce it with "sudo" - see below:

$ sudo amixer set Master toggle
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to
connect: Connection refused

amixer: Mixer attach default error: Connection refused

From reading around, I came to learn that this can be caused by a
missing "cookie" file.
However, even copying the /home/myuser/.config/pulse/cookie file to
/root/.config/pulse/cookie did not solve this issue.

Question 0: Is there any way to get logging information about these
denials, from pulseaudio? The usual advice is to run pulseaudio as a
non-daemon, with "-vvvv" option. I can do this, but even so, none of
these "Connection refused" incidents appear.
Is there somewhere else I should look?

Question 1:
What other reason could there be for this "Connection refused" from
pulse? Any ideas?
Is there any good way for me to confirm that my copied cookie file is
correct, to try to narrow down the problem?

So, I abandoned that approach. Even in the best case, this would
require re-copying the cookie every time I rebooted, or having my
script figure out who spawned pulseaudio, then look in their user
directory, etc. Seems hacky to me.

I learned about "system mode", but given that the developers
themselves say it is unsupported and bad, I am not touching that. Nor
do I trust all that pulseaudio code running as root (:

Next, I found out about the unix socket authentication options in
/etc/pulse/default.pa
I created /etc/pulse/client.conf, and added:

default-server = unix:/tmp/pulse-access-socket

And made a corresponding change in /etc/pulse/default.pa:

load-module module-native-protocol-unix auth-anonymous=1
socket=/tmp/pulse-access-socket

But this does not seem to work.
Looking at the manpages, there are some hints that maybe these options
only apply in system mode? I am not sure...

Question 2:
Can anyone confirm or deny that that method is legitimate?

And really, any other suggestions of how to get this to work are welcome.

Thanks
-John
Sean Greenslade
2015-12-23 05:50:38 UTC
Permalink
Post by John W
Hello,
I'm trying to make the mute/unmute key on my laptop work.
It generates acpi events, but does not generate XF86AudioMute X11
message - In fact, I prefer it to be that way, since I don't want to
rely upon X11 running in order to do this.
I'm trying to figure out the "right" way to do this.
N.B.: It is my understanding that running in system mode, while it may
work, is not the "right" way to do this. I am looking for an
alternative to that, if possible.
My acpi script runs (as root), and I want it to toggle the mute state.
I tried "amixer set Master toggle", but that doesn't work as root.
$ sudo amixer set Master toggle
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to
connect: Connection refused
amixer: Mixer attach default error: Connection refused
From reading around, I came to learn that this can be caused by a
missing "cookie" file.
However, even copying the /home/myuser/.config/pulse/cookie file to
/root/.config/pulse/cookie did not solve this issue.
Question 0: Is there any way to get logging information about these
denials, from pulseaudio? The usual advice is to run pulseaudio as a
non-daemon, with "-vvvv" option. I can do this, but even so, none of
these "Connection refused" incidents appear.
Is there somewhere else I should look?
What other reason could there be for this "Connection refused" from
pulse? Any ideas?
Is there any good way for me to confirm that my copied cookie file is
correct, to try to narrow down the problem?
So, I abandoned that approach. Even in the best case, this would
require re-copying the cookie every time I rebooted, or having my
script figure out who spawned pulseaudio, then look in their user
directory, etc. Seems hacky to me.
I learned about "system mode", but given that the developers
themselves say it is unsupported and bad, I am not touching that. Nor
Next, I found out about the unix socket authentication options in
/etc/pulse/default.pa
default-server = unix:/tmp/pulse-access-socket
load-module module-native-protocol-unix auth-anonymous=1
socket=/tmp/pulse-access-socket
But this does not seem to work.
Looking at the manpages, there are some hints that maybe these options
only apply in system mode? I am not sure...
Can anyone confirm or deny that that method is legitimate?
And really, any other suggestions of how to get this to work are welcome.
Thanks
-John
_______________________________________________
pulseaudio-discuss mailing list
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Have you seen this:

https://github.com/graysky2/pulseaudio-ctl

That's how I make the media keys on my machines work. I use my DE / WM's global shortcuts to trigger the scripts.

Also, IIRC amixer is for alsa. If you want to control pulse, that's probably the wrong way to do it, even if it did work.

--Sean
Tanu Kaskinen
2015-12-23 06:10:06 UTC
Permalink
Post by John W
Hello,
I'm trying to make the mute/unmute key on my laptop work.
It generates acpi events, but does not generate XF86AudioMute X11
message - In fact, I prefer it to be that way, since I don't want to
rely upon X11 running in order to do this.
I'm trying to figure out the "right" way to do this.
N.B.: It is my understanding that running in system mode, while it may
work, is not the "right" way to do this. I am looking for an
alternative to that, if possible.
My acpi script runs (as root), and I want it to toggle the mute state.
I tried "amixer set Master toggle", but that doesn't work as root.
    $ sudo amixer set Master toggle
    ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to
connect: Connection refused
    amixer: Mixer attach default error: Connection refused
From reading around, I came to learn that this can be caused by a
missing "cookie" file.
However, even copying the /home/myuser/.config/pulse/cookie file to
/root/.config/pulse/cookie did not solve this issue.
Question 0: Is there any way to get logging information about these
denials, from pulseaudio? The usual advice is to run pulseaudio as a
non-daemon, with "-vvvv" option. I can do this, but even so, none of
these "Connection refused" incidents appear.
Is there somewhere else I should look?
What other reason could there be for this "Connection refused" from
pulse? Any ideas?
Is there any good way for me to confirm that my copied cookie file is
correct, to try to narrow down the problem?
"Connection refused" doesn't mean that the daemon refused the client
connection (that would be "Access denied" or something like that).
"Connection refused" means that the client didn't find the daemon. If
you meant to connect to the pulseaudio daemon of "myuser" under "root",
that will fail, because root will look for root's pulseaudio daemon
socket, not myuser's daemon socket.
Post by John W
So, I abandoned that approach. Even in the best case, this would
require re-copying the cookie every time I rebooted, or having my
script figure out who spawned pulseaudio, then look in their user
directory, etc. Seems hacky to me.
I learned about "system mode", but given that the developers
themselves say it is unsupported and bad, I am not touching that. Nor
It's not true that the system mode is unsupported, and pulseaudio will
run under the user "pulse" in the system mode, not under root. That
said, using the system mode doesn't seem like the right solution in
this case.
Post by John W
Next, I found out about the unix socket authentication options in
/etc/pulse/default.pa
    default-server = unix:/tmp/pulse-access-socket
    load-module module-native-protocol-unix auth-anonymous=1
socket=/tmp/pulse-access-socket
But this does not seem to work.
Looking at the manpages, there are some hints that maybe these options
only apply in system mode? I am not sure...
The options aren't specific to the system mode. Without error messages,
I don't know why it didn't work. If there are multiple users running
pulseaudio, one problem would be all of them try to listen on the same
socket, which will inevitably fail.
Post by John W
Can anyone confirm or deny that that method is legitimate?
And really, any other suggestions of how to get this to work are welcome.
What do you want to mute? All sinks, including bluetooth etc? Or only
the internal sound card? If it's sufficient to just mute one alsa sound
card, you could use amixer to mute the hardware directly. PulseAudio
will notice that and update its internal state accordingly. This is the
command:

amixer -c0 set Master toggle

"-c0" may refer to the wrong sound card, though (and it may refer to a
different sound card after rebooting). "-cNAME" is better, where NAME
is the sound card name shown in brackets in /proc/asound/cards.

-- 
Tanu
John W
2015-12-30 20:11:41 UTC
Permalink
Post by Tanu Kaskinen
It's not true that the system mode is unsupported
I've seen this link referenced a few places. Maybe it's out of date or
wrong, but definitely seems pretty clear on the point:
http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/

It mentions "You are using PA against the explicit recommendations of
the maintainers...".

It is good to know that PA will run as the 'pulse' user, though.
Post by Tanu Kaskinen
Post by John W
Next, I found out about the unix socket authentication options in
/etc/pulse/default.pa
...
The options aren't specific to the system mode. Without error messages,
I don't know why it didn't work. If there are multiple users running
pulseaudio, one problem would be all of them try to listen on the same
socket, which will inevitably fail.
I only want to run the daemon once, but I want multiple users (in my
case, the "main" user as well as root, via the acpid script) to be
able to communicate with it to affect the audio.

You mention error messages - I would love to provide better ones. Do
you know any way to?
Perhaps a way to see what PA is getting from its configuration files,
what the final "effective config" is at the end of the process, etc?
Post by Tanu Kaskinen
If it's sufficient to just mute one alsa sound
card, you could use amixer to mute the hardware directly. PulseAudio
will notice that and update its internal state accordingly. This is the
amixer -c0 set Master toggle
"-c0" may refer to the wrong sound card, though (and it may refer to a
different sound card after rebooting). "-cNAME" is better, where NAME
is the sound card name shown in brackets in /proc/asound/cards.
I have tried the "-c" option, and it has ... "sort of" success (:

In particular, mute works, but unmute does not.
It seems that mute will affect the "mono" as well as stereo L/R
channels, but unmute only affects mono. So the effect is that it stays
muted.

I am not at the machine right now, but can provide the full output
from that process later.

Thanks for your help
-John
John W
2015-12-31 07:13:54 UTC
Permalink
Post by John W
Post by Tanu Kaskinen
amixer -c0 set Master toggle
"-c0" may refer to the wrong sound card, though (and it may refer to a
different sound card after rebooting). "-cNAME" is better, where NAME
is the sound card name shown in brackets in /proc/asound/cards.
...
I am not at the machine right now, but can provide the full output
from that process later.
Here's that behavior I was describing:

$ amixer get Master # run as the "normal" user, who spawned pulseaudio
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 65536 [100%] [on]
Front Right: Playback 65536 [100%] [on]
$ # I can hear sound right now
$ sudo amixer -c 0 set Master mute
Simple mixer control 'Master',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback 0 - 127
Mono: Playback 127 [100%] [0.00dB] [off]
$ # I hear no sound - this is good!
$ sudo amixer -c 0 set Master unmute
Simple mixer control 'Master',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback 0 - 127
Mono: Playback 127 [100%] [0.00dB] [on]
$ # Alas, it is still muted ):
$ amixer get Master
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 65536 [100%] [off]
Front Right: Playback 65536 [100%] [off]
$ # Notice the [off] for the L/R outputs, above
$ amixer set Master unmute
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 65536 [100%] [on]
Front Right: Playback 65536 [100%] [on]
$ # Now, I can hear sound again. But I had to run a non-root
command to do that.

-John
Tanu Kaskinen
2015-12-31 07:28:59 UTC
Permalink
Post by John W
Post by Tanu Kaskinen
It's not true that the system mode is unsupported
I've seen this link referenced a few places. Maybe it's out of date or
http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/
It mentions "You are using PA against the explicit recommendations of
the maintainers...".
The wiki page is unnecessarily negative.
Post by John W
It is good to know that PA will run as the 'pulse' user, though.
Post by Tanu Kaskinen
Post by John W
Next, I found out about the unix socket authentication options in
/etc/pulse/default.pa
...
The options aren't specific to the system mode. Without error messages,
I don't know why it didn't work. If there are multiple users running
pulseaudio, one problem would be all of them try to listen on the same
socket, which will inevitably fail.
I only want to run the daemon once, but I want multiple users (in my
case, the "main" user as well as root, via the acpid script) to be
able to communicate with it to affect the audio.
You mention error messages - I would love to provide better ones. Do
you know any way to?
Perhaps a way to see what PA is getting from its configuration files,
what the final "effective config" is at the end of the process, etc?
Well, the error message from "pactl info" would be the first step. If
it's "connection refused", either the socket doesn't exist, or the
option you set in /etc/pulse/client.conf didn't have effect.

But anyway, I don't think loading an extra instance of module-native-
protocol-unix is the best alternative here.
Post by John W
Post by Tanu Kaskinen
If it's sufficient to just mute one alsa sound
card, you could use amixer to mute the hardware directly. PulseAudio
will notice that and update its internal state accordingly. This is the
amixer -c0 set Master toggle
"-c0" may refer to the wrong sound card, though (and it may refer to a
different sound card after rebooting). "-cNAME" is better, where NAME
is the sound card name shown in brackets in /proc/asound/cards.
In particular, mute works, but unmute does not.
It seems that mute will affect the "mono" as well as stereo L/R
channels, but unmute only affects mono. So the effect is that it stays
muted.
I don't think the channels are relevant here. The problem is that when
you mute Master, PulseAudio notices that the current audio path got
muted, updates its own sink mute status, and that in turn causes
PulseAudio to mute also other mixer controls in the same path (likely
Speaker or Headphone). When you then unmute Master, the mute state in
PulseAudio doesn't change, because Speaker/Headphone are still muted in
alsa (this behaviour can probably be regarded as a bug in PulseAudio,
fixes welcome).

You could do multiple amixer calls to unmute all necessary controls,
but if you switch between headphones and speakers, the script gets a
bit more complicated, since you have to first figure out which path is
currently active.

If you only need to care about root getting access to your main user
(that is, you're the only human user of the laptop), I think the
easiest solution would be to use "sudo --user=john --set-home pactl
set-sink-mute SINK toggle". Replace SINK with the alsa sink name, you
can find the name with "pactl list sinks".

-- 
Tanu
John W
2016-01-14 05:26:48 UTC
Permalink
Post by Tanu Kaskinen
If you only need to care about root getting access to your main user
(that is, you're the only human user of the laptop), I think the
easiest solution would be to use "sudo --user=john --set-home pactl
set-sink-mute SINK toggle". Replace SINK with the alsa sink name, you
can find the name with "pactl list sinks".
Thanks for the 'pactl ...' suggestion; that did work (with proper user
supplied, etc).

For the benefit of others, note that I did have to go through a little
slice of SELinux hell to get it to work from the acpid script. You
can't just run "pactl" commands from the acpid security context
out-of-the-box, it would seem.

I filed a bug for that issue, but who knows when or if that might be
addressed: https://bugzilla.redhat.com/show_bug.cgi?id=1298432


This solution still does have the downside of needing to know what
user to target. I am determining that by looking at who ran the
'pulseaudio -D' command, but that's a bit lame. Maybe the more
"proper" solution would be to run in system mode, but that still
leaves me a little uneasy.

Loading...