smasher164 / pw-volume

Basic interface to PipeWire volume controls
MIT License
77 stars 10 forks source link

First `change`ing after Pipewire started lower output volume #11

Closed mizzunet closed 2 years ago

mizzunet commented 2 years ago

This is how it is,

  1. Starts pipewire and wireplumber
  2. Plays some audio
  3. pw-volume status says percentage is 1. Definitely, current audio output is not 1%
  4. any change, cause actual output to lower.

I think, the percentage is wrong at 3rd step, actually it might some higher, say 30%, while at 4th step, when I changed for 1%+, the actual output lowers. Means the sound really becomes 2%.

So, I guess, we need to have a look how pw-volume got incorrect percent inititialy, after launching pipewire.

I'm using Artix with OpenRC as init.

mizzunet commented 2 years ago

How was it to check volume level with pw-cli?

smasher164 commented 2 years ago

Thanks for providing such detailed information in the issue! I agree, it seems like the volume that pw-volume is reporting on your system doesn't match what it should be.

Here's what the output looks like on my system:

$ pw-cli enum-params 44 Props
  Object: size 680, type Spa:Pod:Object:Param:Props (262146), id Spa:Enum:ParamId:Props (2)
    Prop: key Spa:Pod:Object:Param:Props:volume (65539), flags 00000000
      Float 1.000000
    Prop: key Spa:Pod:Object:Param:Props:mute (65540), flags 00000000
      Bool false
    Prop: key Spa:Pod:Object:Param:Props:channelVolumes (65544), flags 00000000
      Array: child.size 4, child.type Spa:Float
        Float 0.750000
        Float 0.750000
...

As you can see, channelVolumes is an array containing [0.75, 0.75]. And pw-volume status reports

$ pw-volume status
{"percentage":8, "tooltip":"7.5%"}
mizzunet commented 2 years ago

To clarify, you are now running the latest binary I uploaded (v0.2.0) correct? Yep.

pw-cli enum-params 39 Props

  1. Just after pipewire and wireplumber,

    ...
    Prop: key Spa:Pod:Object:Param:Props:volume (65539), flags 00000000
      Float 1.000000
    Prop: key Spa:Pod:Object:Param:Props:mute (65540), flags 00000000
      Bool false
    Prop: key Spa:Pod:Object:Param:Props:channelVolumes (65544), flags 00000000
      Array: child.size 4, child.type Spa:Float
        Float 0.064012
        Float 0.064012
    ...
  2. After change +1%

    ...
    Prop: key Spa:Pod:Object:Param:Props:volume (65539), flags 00000000
      Float 1.000000
    Prop: key Spa:Pod:Object:Param:Props:mute (65540), flags 00000000
      Bool false
    Prop: key Spa:Pod:Object:Param:Props:channelVolumes (65544), flags 00000000
    Array: child.size 4, child.type Spa:Float
      Float 0.164012
      Float 0.164012
    ...

So, it's Pipewire that reports incorrect parameter.

smasher164 commented 2 years ago

Yup, I notice this on my system as well now.

I'm wondering if there's some other way to get the true volume.

Edit: It seems that others have experienced issues with pipewire reporting inaccurate volume too? https://github.com/jaor/xmobar/issues/535

mizzunet commented 2 years ago

Edit: It seems that others have experienced issues with pipewire reporting inaccurate volume too? jaor/xmobar#535

pamixer --get-volume, pavucontrol and Waybar volume module displays the real outpu percent if pulsewire-pulse is running.

EDIT: does pipewire have pavucontrol similar tool? if it does, we can take a look the way that does

smasher164 commented 2 years ago

Yeah pamixer reports 74% unless I use pulseaudio tools to change volume. It seems that each of these engines (alsa, jack, pulseaudio) maintain their own state about volume, that pipewire doesn't know about. And some range from 0-150% of volume capacity, where pw-volume stays strictly in 0-100.

Looking at this issue: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1475, my guess is that this comes from running pulseaudio and pipewire at the same time? I'll investigate more.

smasher164 commented 2 years ago

I uninstalled pulseaudio (and disabled pulseaudio emulation) and rebooted. I confirm that I don't see this weird behavior anymore.

I'd like to have the pulseaudio emulation still running, but I suspect that applications default to going through pulseaudio, so there needs to be a way to opt out of that in order to use pipewire volume accurately.

Edit: Ignore this comment, I was wrong.

mizzunet commented 2 years ago

Maybe we can ask this issue on #pipewire matrix group

smasher164 commented 2 years ago

Just so you know, I haven't forgotten about this. I just recently joined a new job, and it'll take some time before I can wind down and attend to this. Hope you can understand!

smasher164 commented 2 years ago

I think I ended up figuring out the issue. I've been setting the stream volume instead of the output device volume all this time.

In pulseaudio terminology, I've been setting the sink input volume, instead of the sink volume.

The correct way to do it is https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Migrate-PulseAudio#sinksource-port-volumemuteport-latency.

I'll have to rewrite a bunch of the logic to address this. After getting the node id, I have to look up its device id and card profile device. With the device id, I look up its active routes, and execute the command

pw-cli s <device-id> Route '{ index: <route-index>, device: <card-profile-device>, props: { mute: false, channelVolumes: [ 0.5, 0.5 ], save: true } }'

I'll try to send out a change for this this week, along with other mic-related updates.

smasher164 commented 2 years ago

And another thing, pipewire saves its volume state in the ~/.local/state/ directory. Although, with the approach in the previous comment, we don't need that local state anymore.

smasher164 commented 2 years ago

The latest release https://github.com/smasher164/pw-volume/releases/tag/v0.3.0 should have the fix. Let me know if it works for you.