commit 45deefea71b908e2a0019b5b1fff34a89d80bb22
parent 32ed3b063534d51ca2c4c7a83ca6eeff9e599a05
Author: Spenser Truex <truex@equwal.com>
Date: Wed, 20 Jan 2021 13:02:28 -0800
Add support for the 'status volume' PROTOCOL
Previously this was documented in the PROTOCOL document, though never
implemented, and it is a very useful command.
The other unimplemented parts of the PROTOCOL are
status elapsed: total time elapsed within current song in seconds (not implemented)
status duration: total song duration in seconds (not implemented)
I tested the alsa and sndio variants. The FIFO variant is just always
100.
Test case (alsa or sndio):
$ echo 'status volume' | nc -NU $SOCK
volume: 100
OK
$ echo 'volume 10' | nc -NU $SOCK
volume: 10
OK
$ echo 'status volume' | nc -NU $SOCK
volume: 10
OK
$
Test case (FIFO):
$ echo 'status volume' | nc -NU $SOCK
volume: 100
OK
$ echo 'volume 10' | nc -NU $SOCK
volume: 100 <----- 100
OK
$ echo 'status volume' | nc -NU $SOCK
volume: 100 <----- 100
OK
$
Diffstat:
7 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/PROTOCOL b/PROTOCOL
@@ -78,8 +78,8 @@ Possible states:
songid: songid of the current song stopped on or playing
playback: either play, stop or pause
volume: 0-100
- elapsed: total time elapsed within current song in seconds
- duration: total song duration in seconds
+ elapsed: total time elapsed within current song in seconds (not implemented)
+ duration: total song duration in seconds (not implemented)
wait event-name
Subscribe to the provided event. When the event triggers, a reply will
diff --git a/alsa.c b/alsa.c
@@ -10,6 +10,7 @@
static snd_pcm_t *hdl;
static int framesize;
static const char *device = "default"; /* TODO: make configurable? */
+int alsavolstatus = DEFAULTVOL;
static int
alsavol(int vol)
@@ -51,6 +52,7 @@ alsavol(int vol)
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
snd_mixer_selem_set_playback_volume_all(elem, vol * max / 100);
+ alsavolstatus = vol;
snd_mixer_close(mixerhdl);
return 0;
@@ -115,8 +117,10 @@ alsaclose(void)
}
Output alsaoutput = {
+ .volstatus = &alsavolstatus,
.vol = alsavol,
.open = alsaopen,
.play = alsaplay,
.close = alsaclose,
};
+
diff --git a/cmd.c b/cmd.c
@@ -32,7 +32,10 @@ cmdstatus(int fd, char *arg)
} else if (!strncmp(arg, "single", 7)) {
r = 1;
dprintf(fd, "single: %d\n", (getplaylistmode() & SINGLE) == 1);
- } else if (!strncmp(arg, "songid", 7)) {
+ } else if (!strncmp(arg, "volume", 7)) {
+ r = 1;
+ dprintf(fd, "volume: %d\n", getvol());
+ } else if (!strncmp(arg, "songid", 7)) {
r = 1;
s = getcursong();
diff --git a/fifo.c b/fifo.c
@@ -12,6 +12,8 @@
static int fifofd = -1;
+int fifovolstatus = DEFAULTVOL;
+
static int
fifovol(int vol)
{
@@ -69,6 +71,7 @@ fifoclose(void)
}
Output fifooutput = {
+ .volstatus = &fifovolstatus,
.vol = fifovol,
.open = fifoopen,
.play = fifoplay,
diff --git a/output.c b/output.c
@@ -119,6 +119,20 @@ openoutputs(void)
return r;
}
+int
+getvol(void)
+{
+ Outputdesc *desc;
+ size_t i;
+ for (i = 0; i < LEN(outputdescs); i++) {
+ desc = &outputdescs[i];
+ if (!desc->enabled)
+ continue;
+ return *desc->output->volstatus;
+ }
+ return -1;
+}
+
static int
closeoutput(Outputdesc *desc)
{
@@ -245,8 +259,10 @@ setvol(int vol)
desc = &outputdescs[i];
if (!desc->enabled)
continue;
- if (desc->output->vol(vol) < 0)
+ if (desc->output->vol(vol) < 0) {
r = -1;
+ *desc->output->volstatus = vol;
+ }
}
return r;
}
diff --git a/sad.h b/sad.h
@@ -4,6 +4,7 @@
#define LEN(x) (sizeof (x) / sizeof *(x))
#define PROTOCOLVERSION "0.0"
+#define DEFAULTVOL 100
typedef struct {
char *name;
@@ -40,6 +41,7 @@ typedef struct {
} Decoder;
typedef struct {
+ int *volstatus;
int (*vol)(int);
int (*open)(Format *);
int (*play)(void *, size_t);
@@ -127,6 +129,7 @@ int enableoutput(const char *);
int disableoutput(const char *);
int playoutputs(Format *, void *, size_t);
int setvol(int);
+int getvol(void);
/* notify.c */
extern Eventdesc Eventmap[];
diff --git a/sndio.c b/sndio.c
@@ -8,6 +8,7 @@
#include "sad.h"
static struct sio_hdl *hdl;
+int sndiovolstatus = DEFAULTVOL;
static int
sndiovol(int vol)
@@ -16,6 +17,7 @@ sndiovol(int vol)
warnx("sio_setvol: failed");
return -1;
}
+ sndiovolstatus = vol;
return 0;
}
@@ -78,8 +80,10 @@ sndioclose(void)
}
Output sndiooutput = {
+ .volstatus = &sndiovolstatus,
.vol = sndiovol,
.open = sndioopen,
.play = sndioplay,
.close = sndioclose,
};
+