sad

simple audio daemon
git clone git://git.2f30.org/sad
Log | Files | Refs | LICENSE

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:
MPROTOCOL | 4++--
Malsa.c | 4++++
Mcmd.c | 5++++-
Mfifo.c | 3+++
Moutput.c | 18+++++++++++++++++-
Msad.h | 3+++
Msndio.c | 4++++
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, }; +