nicklan / pnmixer

Volume mixer for the system tray
GNU General Public License v3.0
152 stars 32 forks source link

(default) or any other sound card doesn't work properly #170

Closed nazar-pc closed 6 years ago

nazar-pc commented 6 years ago

I have USB sound card and occasionally it gets disconnected. When such even happens, PNMixer switches its (default) card (or whatever was selected previously changes to (default)) and suddenly starts changing HDMI sound volume (from GPU) instead of USB sound card, which PulseAudio correctly catches and uses by default.

The only workaround is to go to settings and manually switch card to USB sound card and it starts working again.

hasufell commented 6 years ago

This isn't a bug, this is expected behavior (default is a very basic feature). I don't see any fix or even feature proposal without an explanation what behavior you actually want. Also note that PulseAudio is not supported and it's not clear to me how you would use Alsa to achieve something similar.

nazar-pc commented 6 years ago

Expected behavior is that (default) changes the volume of currently selected sound card for output (by PulseAudio I guess, but not sure). However, (default) seems to correspond to sound card that was selected during PNMixer start.

I can select my USB sound card explicitly in settings, but on re-connection it resets to (default) and I have to reconfigure this app again.

I can make a screencast if necessary.

hasufell commented 6 years ago

Expected behavior is that (default) changes the volume of currently selected sound card for output (by PulseAudio I guess, but not sure

Again: PulseAudio is not supported

However, (default) seems to correspond to sound card that was selected during PNMixer start.

Nah, it will just pick the first one that ALSA lists. If that changes, then it also changes, which is expected.

nazar-pc commented 6 years ago

Again: PulseAudio is not supported

Understood.

If that changes, then it also changes, which is expected.

Is it possible to make it prefer the sound card that I've previously selected if one becomes available again?

elboulangero commented 6 years ago

Hey @nazar-pc,

I just checked the code and confirm everything that @hasufell just said.

Now let me add some more details.

When you start PNMixer, it looks for the soundcard that you configured in the settings, find it, then "enable" it for volume changing. It monitors this particular card for any disconnection. If a disconnection happens, it will load another card, the first one available. The first card is defined as the first card in the list of audio cards returned by ALSA.

So you can already check that after disconnecting your USB device, PNMixer picks up another card (whatever it is), and now acts on this card. If you enabled the popup notifications, then you will have a popup message that tells you just that. Additionally, if you let your mouse cursor on the icon, you should get a tooltip which tells you which card is currently selected (depends on your desktop, it does not work on GNOME for example). At last, if you launch PNMixer from a console (please ensure that you don't have two PNMixer instances running at the same time) with the command pnmixer -d, you will get plenty of information as well.

So you have a few options to see which card PNMixer selects after you unplug your USB soundcard. PNMixer behavior is dumb, it's just a fallback, not an attempt to be smart.

Is it possible to make it prefer the sound card that I've previously selected if one becomes available again?

Not in PNMixer, however I think you can configure that in ALSA. Then you would have to try, and see if PNMixer respects the order configured in ALSA, or not. This has never been tested.

At last, let me finish with another additional details: PNMixer only monitor the selected soundcard for disconnection. That's all. So when you plug again your USB soundcard afterward, PNMixer won't be notified, and will not switch back to your USB soundcard.

Adding such feature would be a serious rewrite of the code in alsa.c and audio.c, which is not something I can do unfortunately. If you're a C developer and really care about this issue, feel free to dive in :)

nazar-pc commented 6 years ago

I'm not C developer unfortunately, so it is possible that I fix/implement something myself, but not very likely.

PNMixer only monitor the selected soundcard for disconnection. That's all. So when you plug again your USB soundcard afterward, PNMixer won't be notified, and will not switch back to your USB soundcard.

What about the following: periodically and/or when sound level change is requested check if currently selected sound card is the sound card previously configured in settings window. If it is not - check if it is available now and switch to it if that is the case. This way I think it shouldn't be too complex to implement.

elboulangero commented 6 years ago

At a first glance, that could work. Let me think about it.

hasufell commented 6 years ago

I'd like to try that too, but I have no usb sound card. Is there any other way this could be tested?

nazar-pc commented 6 years ago

Try disconnecting HDMI/DisplayPort monitor and/or front/rear audio if on desktop, something like that. I can compile potential changes for testing if needed.

hasufell commented 6 years ago

@elboulangero

PNMixer picks up another card (whatever it is), and now acts on this card.

I wonder if this is really the most sane default in case of sound card connection loss. An alternative would be to have a new state that properly reflects that the sound card is disconnected (also in the icon) and not do anything.

elboulangero commented 6 years ago

@hasufell

This was intended for people that have a USB sound card, and use it part-time. Like, they have PNMixer up and running with their USB sound card, then they're done with it and disconnect the sound card, and here, magic ! PNMixer keeps working while they're back using their internal sound card.

Honestly, thinking about it now, I agree that it's a bit of a broken behavior. The right implementation should be to monitor all available sound cards (aka monitor connection AND disconnections), and work with them according to their priority (defined by the user in its ALSA configuration file, ie. .asoundrc). Each time there's a connect or disconnect event, PNMixer should take a look at the situation, and change the card it works on if needed.

I think that's the way it should work, however I'm not an ALSA expert, and I didn't do anything related to ALSA for a very long while, so I have no idea if this hypothetic implementation matches the reality of ALSA api.

Plus I'm far from that now, I don't use PNMixer, ALSA, and I don't have an USB sound card either. So I won't be doing anything about all of this :/

hasufell commented 6 years ago

I still use PNMixer, but kinda switched to pulseaudio (steam really stopped working without). I've looked into pulseaudio support in my rust rewrite, but pulseaudio works fundamentally different and we would have to completely switch the behavior. Instead of Gtk being the main entry point to things and having our own signalling system we would need to utilize the asynchronous pulseaudio system and manipulate all of Gtk within pulseaudio callbacks, not the other way around.

nazar-pc commented 6 years ago

I'm using PulseAudio and PNMixer works great as soon as correct sound card is selected.

hasufell commented 6 years ago

That's not what we mean with PulseAudio support. It just works eventually, it doesn't use the PulseAudio API at all. Try mute/unmute and you will see your first bug.

nazar-pc commented 6 years ago

I understand what you mean, but still it works fine for me, including mute/unmute :)

hasufell commented 6 years ago

I doubt unmute actually works.

elboulangero commented 6 years ago

Hey @nazar-pc, can you give a try to this branch https://github.com/nicklan/pnmixer/tree/feature/auto-reload-audio ? I didn't test it.

nazar-pc commented 6 years ago

@elboulangero, branch works great on my system:

debug: /pnmixer/src/audio.c: Preferred card available, audio should be reloaded
debug: /pnmixer/src/audio.c: Unhooking soundcard from the audio system
debug: /pnmixer/src/alsa.c: 'default': Closing mixer
debug: /pnmixer/src/audio.c: ** Dispatching signal 'card cleaned up' from 'unknown', vol=0, has_mute=no, muted=yes
debug: /pnmixer/src/audio.c: Hooking soundcard 'SB Omni Surround 5.1 (PCM)' to the audio system
debug: /pnmixer/src/alsa.c: 'hw:1': Opening mixer
debug: /pnmixer/src/alsa.c: 'hw:1': Looking for playable mixer element 'PCM'
debug: /pnmixer/src/alsa.c: 'hw:1': 1 poll descriptors are now watched
debug: /pnmixer/src/alsa.c: 'hw:1': Card 'SB Omni Surround 5.1' with channel 'PCM' initialized !
debug: /pnmixer/src/audio.c: Soundcard successfully hooked (scroll step: 5, normalize: true)
debug: /pnmixer/src/audio.c: ** Dispatching signal 'card initialized' from 'unknown', vol=48,6874, has_mute=yes, muted=no
debug: /pnmixer/src/audio.c: Setting volume from 48,6874 to 43,6874 (dir: -1)
debug: /pnmixer/src/audio.c: ** Dispatching signal 'values changed' from 'hotkeys', vol=43,3751, has_mute=yes, muted=no
debug: /pnmixer/src/audio.c: Setting volume from 43,3751 to 48,3751 (dir: 1)
debug: /pnmixer/src/audio.c: ** Dispatching signal 'values changed' from 'hotkeys', vol=48,6874, has_mute=yes, muted=no

@hasufell, unmute does work wonderfully. It looks like PulseAudio is listening to ALSA changes and replicates them on its level.

hasufell commented 6 years ago

It looks like PulseAudio is listening to ALSA changes and replicates them on its level.

It's a bit more complicated than that. Which is why it doesn't work consistenly.

hasufell commented 6 years ago

Should this be closed after https://github.com/nicklan/pnmixer/commit/9b23149630c683c664bb74407b9ac359ae42205f ?

nazar-pc commented 6 years ago

Yes! And I'd be thankful if you could publish a new release)

hasufell commented 6 years ago

And I'd be thankful if you could publish a new release

Why so urgent?

nazar-pc commented 6 years ago

To be honest, I'm quite distant from native development and this time failed to figure out how to compile PNMixer so that it can grab resources from /usr/share/pnmixer/ (Ubuntu's package) instead of path to source files used during compilation. Because of this I can't replace packaged binary with fixed one and suffering from the issue that is fixed upstream 😄

If you can help me with it would be great and not so urgent.

hasufell commented 6 years ago

To be honest, I'm quite distant from native development and this time failed to figure out how to compile PNMixer so that it can grab resources from /usr/share/pnmixer/ (Ubuntu's package) instead of path to source files used during compilation.

Why would you do that?

nazar-pc commented 6 years ago

In order to use fixed version months before it reaches Ubuntu repository

hasufell commented 6 years ago

In order to use fixed version months before it reaches Ubuntu repository

I have no idea what that means. If you run pnmixer from the build directory it prefers the local files over /usr/share/pnmixer, which is totally expected. What exactly do you expect? Running new code against old glide definitions? That's a very bad idea.

nazar-pc commented 6 years ago

I'd like to compile PNMixer from master branch of this repository and replace files of currently installed version from Ubuntu repository with compiled version. This way I will have fixed version immediately while still keeping possibility to uninstall/upgrade it with my package manager (in other words I don't have to run an app from directory with source code all the time, creating *.desktop files manually and so on).

it prefers the local files over /usr/share/pnmixer

The issue is that it doesn't prefer local files, it uses them exclusively with absolute paths to files been hard coded in binary and crashes if I move binary anywhere.

hasufell commented 6 years ago

This way I will have fixed version immediately while still keeping possibility to uninstall/upgrade it with my package manager (in other words I don't have to run an app from directory with source code all the time, creating *.desktop files manually and so on).

That's a hack and we don't support that use case. Install it properly, e.g. in a prefix:

mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX="${HOME}"/.local/pnmixer ..
make
make install

Then symlink $HOME/.local/pnmixer/bin/pnmixer somewhere or adjust your PATH accordingly.

Then to uninstall you just delete the entire $HOME/.local/pnmixer directory.

nazar-pc commented 6 years ago

I know it is a hack:)

Will try install prefix, seems to be exactly what I need, thanks!

nazar-pc commented 6 years ago

I've got desired behavior with cmake -DCMAKE_INSTALL_PREFIX=/usr, thank you!

hasufell commented 6 years ago

I've got desired behavior with cmake -DCMAKE_INSTALL_PREFIX=/usr, thank you!

That's unsupported. To anyone else reading that: don't do it. Either install only via your distro package manager or install in a prefix directory you fully control (cmake has no uninstall rules last I checked and those are unreliable anyway). Pnmixer works in any prefix.

elboulangero commented 6 years ago

I've got desired behavior with cmake -DCMAKE_INSTALL_PREFIX=/usr, thank you!

Yep you definitely shouldn't do that, /usr is where your package manager install stuff, and you should never mess with it :) That's exactly why @hasufell suggests a prefix like $HOME/.local/pnmixer.

nazar-pc commented 6 years ago

I know what I'm doing folks and I'm fully aware that it is unsupported, no worries:)