commit - 069e653bc1e64578b0a97465a2016b7dc0bf3f56
commit + 06ceb3767eb7e480de05cd50f4fbaf75fb3322a2
blob - 7b9eb922ca793410bf8c7c3ef53d5387f0cf41dd
blob + ed6eac93eeae2b298b126764266afb1ebaf7ca0e
--- Makefile
+++ Makefile
DISTNAME = ${PROG}-${VERSION}
SOURCES = amused.c \
+ audio_sndio.c \
compats.c \
control.c \
ctl.c \
# supports it.
-include amused.d
+-include audio_sndio.d
-include compats.d
-include control.d
-include ctl.d
blob - fc49a771a10bbb1a9f2e3fa8767085c0d51fe99b
blob + 8e43ca26a080662b1a3be57c37217cdb5ac8953d
--- amused.h
+++ amused.h
};
struct playlist;
+struct pollfd;
/* amused.c */
void spawn_daemon(void);
void main_send_status(struct imsgev *);
void main_seek(struct player_seek *);
+/* audio_*.c */
+int audio_open(void (*)(void *, int));
+int audio_setup(unsigned int, unsigned int, unsigned int,
+ struct pollfd *);
+int audio_nfds(void);
+int audio_pollfd(struct pollfd *, int);
+int audio_revents(struct pollfd *);
+size_t audio_write(const void *, size_t);
+int audio_flush(void);
+int audio_stop(void);
+
/* ctl.c */
__dead void usage(void);
__dead void ctl(int, char **);
blob - /dev/null
blob + 3a44d164a81a7d7317f6284e0b8c84aad10e3e30 (mode 644)
--- /dev/null
+++ audio_sndio.c
+/*
+ * Copyright (c) 2023 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <poll.h>
+#include <sndio.h>
+#include <stdio.h>
+
+#include "amused.h"
+#include "log.h"
+
+static struct sio_hdl *hdl;
+static struct sio_par par;
+static int stopped = 1;
+
+int
+audio_open(void (*onmove_cb)(void *, int))
+{
+ if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 1)) == NULL)
+ return -1;
+
+ sio_onmove(hdl, onmove_cb, NULL);
+ return 0;
+}
+
+int
+audio_setup(unsigned int bits, unsigned int rate, unsigned int channels,
+ struct pollfd *pfds)
+{
+ int nfds, fpct;
+
+ fpct = (rate * 5) / 100;
+
+ /* don't stop if the parameters are the same */
+ if (bits == par.bits && channels == par.pchan &&
+ par.rate - fpct <= rate && rate <= par.rate + fpct) {
+ if (stopped)
+ goto start;
+ return 0;
+ }
+
+ again:
+ if (!stopped) {
+ sio_stop(hdl);
+ stopped = 1;
+ }
+
+ sio_initpar(&par);
+ par.bits = bits;
+ par.rate = rate;
+ par.pchan = channels;
+ if (!sio_setpar(hdl, &par)) {
+ if (errno == EAGAIN) {
+ nfds = sio_pollfd(hdl, pfds, POLLOUT);
+ if (poll(pfds, nfds, INFTIM) == -1)
+ fatal("poll");
+ goto again;
+ }
+ log_warnx("invalid params (bits=%u, rate=%u, channels=%u)",
+ bits, rate, channels);
+ return -1;
+ }
+ if (!sio_getpar(hdl, &par)) {
+ log_warnx("can't get params");
+ return -1;
+ }
+
+ if (par.bits != bits || par.pchan != channels) {
+ log_warnx("failed to set params");
+ return -1;
+ }
+
+ /* TODO: check sample rate? */
+
+ start:
+ if (!sio_start(hdl)) {
+ log_warn("sio_start");
+ return -1;
+ }
+ stopped = 0;
+ return 0;
+}
+
+int
+audio_nfds(void)
+{
+ return sio_nfds(hdl);
+}
+
+int
+audio_pollfd(struct pollfd *pfds, int events)
+{
+ return sio_pollfd(hdl, pfds, events);
+}
+
+int
+audio_revents(struct pollfd *pfds)
+{
+ return sio_revents(hdl, pfds);
+}
+
+size_t
+audio_write(const void *buf, size_t len)
+{
+ return sio_write(hdl, buf, len);
+}
+
+int
+audio_flush(void)
+{
+ stopped = 1;
+ return sio_flush(hdl);
+}
+
+int
+audio_stop(void)
+{
+ stopped = 1;
+ return sio_stop(hdl);
+}
blob - a20334041994cda28a95a0e42e2bc12e2877b478
blob + 1bdef9ba7768c972ef5db3b2676830406134982e
--- player.c
+++ player.c
#include <errno.h>
#include <poll.h>
#include <signal.h>
-#include <sndio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "log.h"
#include "xmalloc.h"
-struct sio_hdl *hdl;
-struct sio_par par;
struct pollfd *player_pfds;
static struct imsgbuf *ibuf;
-static int stopped = 1;
static int nextfd = -1;
static int64_t samples;
static int64_t duration;
+static unsigned int current_rate;
volatile sig_atomic_t halted;
int
player_setup(unsigned int bits, unsigned int rate, unsigned int channels)
{
- int nfds, fpct;
-
log_debug("%s: bits=%u, rate=%u, channels=%u", __func__,
bits, rate, channels);
- fpct = (rate*5)/100;
-
- /* don't stop if the parameters are the same */
- if (bits == par.bits && channels == par.pchan &&
- par.rate - fpct <= rate && rate <= par.rate + fpct) {
- if (stopped)
- goto start;
- return 0;
- }
-
-again:
- if (!stopped) {
- sio_stop(hdl);
- stopped = 1;
- }
-
- sio_initpar(&par);
- par.bits = bits;
- par.rate = rate;
- par.pchan = channels;
- if (!sio_setpar(hdl, &par)) {
- if (errno == EAGAIN) {
- nfds = sio_pollfd(hdl, player_pfds + 1, POLLOUT);
- if (poll(player_pfds + 1, nfds, INFTIM) == -1)
- fatal("poll");
- goto again;
- }
- log_warnx("invalid params (bits=%d, rate=%d, channels=%d",
- bits, rate, channels);
- return -1;
- }
- if (!sio_getpar(hdl, &par)) {
- log_warnx("can't get params");
- return -1;
- }
-
- if (par.bits != bits || par.pchan != channels) {
- log_warnx("failed to set params");
- return -1;
- }
-
- /* TODO: check the sample rate? */
-
-start:
- if (!sio_start(hdl)) {
- log_warn("sio_start");
- return -1;
- }
- stopped = 0;
- return 0;
+ current_rate = rate;
+ return audio_setup(bits, rate, channels, player_pfds + 1);
}
void
int64_t seconds;
duration = d;
- seconds = duration / par.rate;
+ seconds = duration / current_rate;
imsg_compose(ibuf, IMSG_LEN, 0, 0, -1, &seconds, sizeof(seconds));
imsg_flush(ibuf);
}
int64_t sec;
samples += delta;
- if (llabs(samples - reported) >= par.rate) {
+ if (llabs(samples - reported) >= current_rate) {
reported = samples;
- sec = samples / par.rate;
+ sec = samples / current_rate;
imsg_compose(ibuf, IMSG_POS, 0, 0, -1, &sec, sizeof(sec));
imsg_flush(ibuf);
if (seek.percent) {
*s = (double)seek.offset * (double)duration / 100.0;
} else {
- *s = seek.offset * par.rate;
+ *s = seek.offset * current_rate;
if (seek.relative)
*s += samples;
}
*s = -1;
while (len != 0) {
- nfds = sio_pollfd(hdl, player_pfds + 1, POLLOUT);
+ nfds = audio_pollfd(player_pfds + 1, POLLOUT);
r = poll(player_pfds, nfds + 1, INFTIM);
if (r == -1)
fatal("poll");
wait = player_pfds[0].revents & (POLLHUP|POLLIN);
if (player_shouldstop(s, wait)) {
- sio_flush(hdl);
- stopped = 1;
+ audio_flush();
return 0;
}
- revents = sio_revents(hdl, player_pfds + 1);
+ revents = audio_revents(player_pfds + 1);
if (revents & POLLHUP) {
if (errno == EAGAIN)
continue;
- fatal("sndio hang-up");
+ fatal("audio hang-up");
}
if (revents & POLLOUT) {
- w = sio_write(hdl, buf, len);
+ w = audio_write(buf, len);
len -= w;
buf += w;
}
}
#endif
- if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 1)) == NULL)
- fatal("sio_open");
+ if (audio_open(player_onmove) == -1)
+ fatal("audio_open");
- sio_onmove(hdl, player_onmove, NULL);
-
/* allocate one extra for imsg */
- player_pfds = calloc(sio_nfds(hdl) + 1, sizeof(*player_pfds));
+ player_pfds = calloc(audio_nfds() + 1, sizeof(*player_pfds));
if (player_pfds == NULL)
fatal("calloc");