Improve Volume Wheel Daemon (Bounty!)


I think I'd prefer the script to check the volume wheel every couple of seconds,even when no sound is playing. It feels odd that the volume controls don't move until a sound plays. For example, I might have left the volume on full but want to start playing the next track quietly. So, I want to turn it down before starting the track.
 
Last edited:
Yes, I think that's the best way to guarantee that the sound is muted if you turn the wheel all the way down prior to a system notification event happening. I'd like it to be a little quicker when a video is actually playing, provided that doesn't pull too much CPU time from the video player. I generally turn the volume up when I enter a noisy area, like walking alongside a road, and turn it down again once I leave the less travelled paths where there's much less noise. Perhaps an up to 2s delay between turning the wheel and the sound changing in such an even would be okay, and it might be nice if after the first tweak it did speed up it's checks so that if you turn it up too high you can quickly turn it down again.
 
I'm confused: Why do we have both the twl6030_gpadc (written by TI) and the palmas_gpadc (written by NVIDIA) drivers in the kernel as options for the pyra? They look to do exactly the same thing but are coded in different styles. 'lsmod' shows that we use the palmas one. The volume control adc driver says its called "palmas_gpadc" (/sys/bus/iio/devices/iio:device3/name). The twl6030_gpadc even has the same channel definitions. Has one got more bugs?

The pyra_defconfig has both available:
986 CONFIG_PALMAS_GPADC=m
990 CONFIG_TWL6030_GPADC=m

I'm browsing the kernel using the "rxi/lite" code editor on my pyra. I start it with "lite ." from the kernel root and search all files for things I'm looking for with <shift>+<ctrl>+<f>. Its a very fast way to search 76k files for a function name!. I wish the default colour scheme was brighter and font slightly bigger.
 
Thanks for testing.
Maybe call snd_mixer_selem_set_playback_volume_all(elem, volume); at the start of your code to set the ALSA volume to full?
No, that would be quite the annoying unexpected behaviour. First, with only one tool running the other value would never be changed anyway, second, some ppl like to set it to eg 90% to reduce noise on some channels, they sure dont want this to be overruled.
I think I'd prefer the script to check the volume wheel every couple of seconds. It feels odd that the volume controls don't move until a sound plays. For example, I might have left the volume on full but want to start playing the next track quietly. So, I want to turn it down before starting the track.
Just dont look at the controls, problem solved. Why would we need a graphical tool when we have a physical wheel to turn?
Note that there is NO delay at all. The volume is synced as soon the sound card is used. That means if you turn the wheel to off the sound will be off even when the icon says otherwise, as soon as a system sound pops up it will be muted before you can hear something.

I can, if thats really what you want, ad an argument that disables the shutdown tho.
I'm confused: Why do we have both the twl6030_gpadc (written by TI) and the palmas_gpadc (written by NVIDIA) drivers in the kernel as options for the pyra?
I think the other one is for monitoring the battery. The pyra wiki needs to have more details. One needs to read the design file, list all hardware and make a table about which software controls which hardware....
 
Just dont look at the controls, problem solved. Why would we need a graphical tool when we have a physical wheel to turn
I wasnt clear. I mean, I'd prefer the script to check the volume wheel every couple of seconds, even when there is no sound playing.
 
Adding this as an option isnt hard, extra for you.
But i dont get why. Isnt that a bit pointless?
 
I think the other one is for monitoring the battery
I don't think twl6030 is even loaded.
Bash:
me@pyra:~$ lsmod | grep palmas
palmas_gpadc           20480  0

me@pyra:~$ lsmod | grep twl6030
 
But i dont get why. Isnt that a bit pointless?
Use case: I've had the music at full blast in headphones. I then want to quietly play something through the speakers in a public place. I stop my loud track and unplug the headphones. I browse for a sound I want to share with the someone sat nearby. I turn the volume wheel down before starting so as not to wake the baby (lion, grandmother, whatever). I then start playing through the speakers, but its still at full blast. The baby screams, the lion eats my grandmother.

I'd have prefered it if the volume control had worked before starting the track.
 
And more....
Following flags and this help page exist now:
Code:
Speed     Delay between polling wheel in μs
          Advised value: 100000 (0.1s)
          Default value: 100000
Range     Expected Maximal wheel value, default: 2000
          Higher values limit the volume, lower allow an overdrive
          Eg: 4000> 50% max volume; 1000> 200% max volume
Timout    Time in seconds after polltime should be reduced to second value
          Disabled when 0, Default: 0
Slow      Same as Speed, applied after Timout seconds
          Advised value: 1000000 (1s)
          Default value: 1000000
Stayon    Disables monitor of Soundcard, never turn polling off
Help      This page oviously

Example: Poll very fast after sound starts playing and then every two seconds after the first 10 seconds:
vwheeld Speed 20000 Timeout 10 Slow 2000000
Example: Always poll slow, no monitoring, limit volume to 50%
vwheeld Speed 1000000 Stayon Range 4000
And there is a verbose file with mucho messages if you really want to see whats going on.

Personally i consider "vwheeld Speed 100000 Timeout 25 Slow 2000000" to be the most practical for everyday use.
Depending on the program the timeout resets after stop/pause/next track. This is the case with deadbeef at least.
Which effectively means i have the high poll rate at the first 25 seconds of each track.

If you really insist to need a feedback in the icon when nothing plays you can mix the timeout with "Stayon" and thus never disable polling and at least have the time reduced.
 

Attachments

  • vol.tar.gz
    6.9 KB · Views: 222
and it might be nice if after the first tweak it did speed up it's checks so that if you turn it up too high you can quickly turn it down again.
Ah i finally got this, so lets say you decide for a slow 4s poll, then accidentally slip and set it to high, it will fry your ears for the next 4 seconds.
You got a point there... Just a line more to add.
 
Wouldn't it be better to have a kernel module do the volume wheel polling (and possibly filtering) and then make sure to properly implement the poll API? Userspace would only be woken up when the value from the ADC has changed.
This would potentially save on battery since there is less code that needs to be run before a decision to change the volume needs to be made. I figure that most of the time, there is actually no change in volume (ADC value) and waking up an userspace application only to figure out that nothing's changed seem like a waste of CPU cycles.
EDIT: This kernel module could of course have a bunch of knobs and dials in sysfs to fine tune the sampling frequency and filtering.
 
  • Like
Reactions: hns
And how would the kernel module know WHEN to poll the wheel?
 
I was thinking at a fixed rate of a few times/second (configurable i sysfs), either using some hardware timer or a regular kernel timer. At regular intervals, schedule an ADC read and wait for the interrupt. At least I got the impression from @ouzle that's how the driver does it
The driver asks for a reading from the ADC and uses an interrupt to get the result. So why should the CPU be busy?
Once a reading is available, do some processing/filtering and, if the result differs from earlier results, wake up user space. That should be a bit more efficient than waking up an userspace application multiple times a second, which needs to switch back to kernel mode again to get the latest value.

I can't imagine reading an ADC value taking up much CPU time (if done right), but after reading this thread a bit more carefully I understand it is a problem. Might be worth doing some bug hunting in the palmas driver?
 
Looks like what I'm looking for is sort of already available in the kernel iio subsystem. Unfortunately, libiio doesn't support iio events yet:
 
Are you volunteering to fix the kernel read?

Anyhow, regardless of how the code looks, even if someone manages to trim down the current kernel read to not cause that much cpu load, polling the wheel will always cause the most power usage in this process.
If we want to save power then turning the polling off as much as possible is the only way to go.
Questioning how this polling works however is an attempt of dusting the dessert. You may be able to remove some grains but it will always stay a dessert,
 
Huh, good idea, i ran a quick test:
457000 471000 >no polling
470000 484000 >0.1s
522000 541000 >0.01s
This is the output of the battery current file, with the MIN/MAX value. There seems to be a trend:
The current always on polling script accounts for 2% of the total power usage.
But take it with a grain of salt, because this number is not averaged and neither does it stay constant over reboots.
Fluctuations of single % need to be monitored for much longer than i did, and with a proper tool, my sys monitor script isnt exactly made for this.
Also note that the sleep command stands for minimal wait time between polls, 0.1 is NOT 10 times as much as 0.01 in this case because it does not count the time for the poll itself in.
So you cant just double polling amounts and assume it takes double the power.

Edit: No wait, my monitor is written in Löve using software rendering doing a complete system monitor polling itself.
I was NOT idle so i cannot use the first number to guess a percentage.
The real number, should be much worse...
 
Last edited:
Back
Top