On Fri, May 22, 2020 at 11:58:23AM +0200, Thomas Vigouroux wrote:
Quoting Ivan Tham (2020-05-22 10:52:21)
I believe you may need to convert it to double before division and round the
volume. My dwms have something similar:

                  return smprintf("%d", (int) rint((double) (val - min) /
                                                   (double) (max - min) * 100));

https://github.com/pickfire/dwms/blob/c2038a4104f4f80aa6f675821c62e87ccfe48bed/dwms.c#L213-L241

Actually, multiplying before might avoid floating point computation and only 
uses integer computation.
Thanks for your answer and suggestion !

Here is an updated patch :

diff --git a/components/volume.c b/components/volume.c
index 61cec90..f2e5b70 100644
--- a/components/volume.c
+++ b/components/volume.c
@@ -72,6 +72,57 @@

                return bprintf("%d", m ? 0 : v * 100 / 255);
        }
+#elif defined(__linux__)
+       #include <alsa/asoundlib.h>
+       #include <alsa/mixer.h>
+
+       const char *
+       vol_perc(const char * card)
+       {
+               long minv, maxv, outvol;
+               snd_mixer_t* handle;
+               snd_mixer_elem_t* elem;
+               snd_mixer_selem_id_t* sid;
+
+               static const char* mix_name = "Master";
+               static int mix_index = 0;
+
+               snd_mixer_selem_id_alloca(&sid);
+
+               /* sets simple-mixer index and name */
+               snd_mixer_selem_id_set_index(sid, mix_index);
+               snd_mixer_selem_id_set_name(sid, mix_name);
+
+               if (snd_mixer_open(&handle, 0) < 0)
+                       return NULL;
+               if (snd_mixer_attach(handle, card) < 0) {
+                       snd_mixer_close(handle);
+                       return NULL;
+               }

There seemed to be a lot of repeated patterns, why not use goto like other C projects to handle failure?

+               if (snd_mixer_selem_register(handle, NULL, NULL) < 0) {
+                       snd_mixer_close(handle);
+                       return NULL;
+               }
+               if (snd_mixer_load(handle) < 0) {
+                       snd_mixer_close(handle);
+                       return NULL;
+               }
+               elem = snd_mixer_find_selem(handle, sid);
+               if (!elem) {
+                       snd_mixer_close(handle);
+                       return NULL;
+               }
+
+               snd_mixer_selem_get_playback_volume_range(elem, &minv, &maxv);
+
+               if(snd_mixer_selem_get_playback_volume(elem, 0, &outvol) < 0) {
+                       snd_mixer_close(handle);
+                       return NULL;
+               }
+
+               snd_mixer_close(handle);
+               return bprintf("%ld", (100 * (outvol - minv)) / (maxv - minv));

If I recall correctly, it is something like:

                const char* buf = NULL;

                ...

                if (failure)
                        goto error;
                ...

                buf = bprintf("%ld", (100 * (outvol - minv)) / (maxv - minv));

error:
                snd_mixer_close(handle);
                return buf;


Not sure if it is better like the other code I have seen but I think it reduces the code duplication.

+       }
#else
        #include <sys/soundcard.h>

diff --git a/config.def.h b/config.def.h
index e06be66..af2197c 100644
--- a/config.def.h
+++ b/config.def.h
@@ -58,6 +58,7 @@ static const char unknown_str[] = "n/a";
 * uptime              system uptime                   NULL
 * username            username of current user        NULL
 * vol_perc            OSS/ALSA volume in percent      mixer file (/dev/mixer)
+ *                                                     sound card name on 
Linux (default)
 * wifi_perc           WiFi signal in percent          interface name (wlan0)
 * wifi_essid          WiFi ESSID                      interface name (wlan0)
 */
diff --git a/config.mk b/config.mk
index 3b32b7c..cd2a234 100644
--- a/config.mk
+++ b/config.mk
@@ -14,7 +14,7 @@ X11LIB = /usr/X11R6/lib
CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE
CFLAGS   = -std=c99 -pedantic -Wall -Wextra -Os
LDFLAGS  = -L$(X11LIB) -s
-LDLIBS   = -lX11
+LDLIBS   = -lX11 -lasound

# compiler and linker
CC = cc

Reply via email to