Blame


1 06ceb376 2023-03-23 op /*
2 06ceb376 2023-03-23 op * Copyright (c) 2023 Omar Polo <op@omarpolo.com>
3 06ceb376 2023-03-23 op *
4 06ceb376 2023-03-23 op * Permission to use, copy, modify, and distribute this software for any
5 06ceb376 2023-03-23 op * purpose with or without fee is hereby granted, provided that the above
6 06ceb376 2023-03-23 op * copyright notice and this permission notice appear in all copies.
7 06ceb376 2023-03-23 op *
8 06ceb376 2023-03-23 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 06ceb376 2023-03-23 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 06ceb376 2023-03-23 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 06ceb376 2023-03-23 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 06ceb376 2023-03-23 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 06ceb376 2023-03-23 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 06ceb376 2023-03-23 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 06ceb376 2023-03-23 op */
16 06ceb376 2023-03-23 op
17 06ceb376 2023-03-23 op #include "config.h"
18 06ceb376 2023-03-23 op
19 06ceb376 2023-03-23 op #include <errno.h>
20 06ceb376 2023-03-23 op #include <limits.h>
21 06ceb376 2023-03-23 op #include <poll.h>
22 06ceb376 2023-03-23 op #include <sndio.h>
23 06ceb376 2023-03-23 op #include <stdio.h>
24 06ceb376 2023-03-23 op
25 06ceb376 2023-03-23 op #include "amused.h"
26 06ceb376 2023-03-23 op #include "log.h"
27 06ceb376 2023-03-23 op
28 06ceb376 2023-03-23 op static struct sio_hdl *hdl;
29 06ceb376 2023-03-23 op static struct sio_par par;
30 06ceb376 2023-03-23 op static int stopped = 1;
31 06ceb376 2023-03-23 op
32 06ceb376 2023-03-23 op int
33 06ceb376 2023-03-23 op audio_open(void (*onmove_cb)(void *, int))
34 06ceb376 2023-03-23 op {
35 06ceb376 2023-03-23 op if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 1)) == NULL)
36 06ceb376 2023-03-23 op return -1;
37 06ceb376 2023-03-23 op
38 06ceb376 2023-03-23 op sio_onmove(hdl, onmove_cb, NULL);
39 06ceb376 2023-03-23 op return 0;
40 06ceb376 2023-03-23 op }
41 06ceb376 2023-03-23 op
42 06ceb376 2023-03-23 op int
43 06ceb376 2023-03-23 op audio_setup(unsigned int bits, unsigned int rate, unsigned int channels,
44 b02dadd3 2023-05-13 op struct pollfd *pfds, int nfds)
45 06ceb376 2023-03-23 op {
46 b02dadd3 2023-05-13 op int fpct;
47 06ceb376 2023-03-23 op
48 06ceb376 2023-03-23 op fpct = (rate * 5) / 100;
49 06ceb376 2023-03-23 op
50 06ceb376 2023-03-23 op /* don't stop if the parameters are the same */
51 06ceb376 2023-03-23 op if (bits == par.bits && channels == par.pchan &&
52 06ceb376 2023-03-23 op par.rate - fpct <= rate && rate <= par.rate + fpct) {
53 06ceb376 2023-03-23 op if (stopped)
54 06ceb376 2023-03-23 op goto start;
55 06ceb376 2023-03-23 op return 0;
56 06ceb376 2023-03-23 op }
57 06ceb376 2023-03-23 op
58 06ceb376 2023-03-23 op again:
59 06ceb376 2023-03-23 op if (!stopped) {
60 06ceb376 2023-03-23 op sio_stop(hdl);
61 06ceb376 2023-03-23 op stopped = 1;
62 06ceb376 2023-03-23 op }
63 06ceb376 2023-03-23 op
64 06ceb376 2023-03-23 op sio_initpar(&par);
65 06ceb376 2023-03-23 op par.bits = bits;
66 06ceb376 2023-03-23 op par.rate = rate;
67 06ceb376 2023-03-23 op par.pchan = channels;
68 06ceb376 2023-03-23 op if (!sio_setpar(hdl, &par)) {
69 06ceb376 2023-03-23 op if (errno == EAGAIN) {
70 b02dadd3 2023-05-13 op sio_pollfd(hdl, pfds, POLLOUT);
71 06ceb376 2023-03-23 op if (poll(pfds, nfds, INFTIM) == -1)
72 06ceb376 2023-03-23 op fatal("poll");
73 06ceb376 2023-03-23 op goto again;
74 06ceb376 2023-03-23 op }
75 06ceb376 2023-03-23 op log_warnx("invalid params (bits=%u, rate=%u, channels=%u)",
76 06ceb376 2023-03-23 op bits, rate, channels);
77 06ceb376 2023-03-23 op return -1;
78 06ceb376 2023-03-23 op }
79 06ceb376 2023-03-23 op if (!sio_getpar(hdl, &par)) {
80 06ceb376 2023-03-23 op log_warnx("can't get params");
81 06ceb376 2023-03-23 op return -1;
82 06ceb376 2023-03-23 op }
83 06ceb376 2023-03-23 op
84 06ceb376 2023-03-23 op if (par.bits != bits || par.pchan != channels) {
85 06ceb376 2023-03-23 op log_warnx("failed to set params");
86 06ceb376 2023-03-23 op return -1;
87 06ceb376 2023-03-23 op }
88 06ceb376 2023-03-23 op
89 06ceb376 2023-03-23 op /* TODO: check sample rate? */
90 06ceb376 2023-03-23 op
91 06ceb376 2023-03-23 op start:
92 06ceb376 2023-03-23 op if (!sio_start(hdl)) {
93 06ceb376 2023-03-23 op log_warn("sio_start");
94 06ceb376 2023-03-23 op return -1;
95 06ceb376 2023-03-23 op }
96 06ceb376 2023-03-23 op stopped = 0;
97 06ceb376 2023-03-23 op return 0;
98 06ceb376 2023-03-23 op }
99 06ceb376 2023-03-23 op
100 06ceb376 2023-03-23 op int
101 06ceb376 2023-03-23 op audio_nfds(void)
102 06ceb376 2023-03-23 op {
103 06ceb376 2023-03-23 op return sio_nfds(hdl);
104 06ceb376 2023-03-23 op }
105 06ceb376 2023-03-23 op
106 06ceb376 2023-03-23 op int
107 b02dadd3 2023-05-13 op audio_pollfd(struct pollfd *pfds, int nfds, int events)
108 06ceb376 2023-03-23 op {
109 06ceb376 2023-03-23 op return sio_pollfd(hdl, pfds, events);
110 06ceb376 2023-03-23 op }
111 06ceb376 2023-03-23 op
112 06ceb376 2023-03-23 op int
113 b02dadd3 2023-05-13 op audio_revents(struct pollfd *pfds, int nfds)
114 06ceb376 2023-03-23 op {
115 06ceb376 2023-03-23 op return sio_revents(hdl, pfds);
116 06ceb376 2023-03-23 op }
117 06ceb376 2023-03-23 op
118 06ceb376 2023-03-23 op size_t
119 06ceb376 2023-03-23 op audio_write(const void *buf, size_t len)
120 06ceb376 2023-03-23 op {
121 06ceb376 2023-03-23 op return sio_write(hdl, buf, len);
122 06ceb376 2023-03-23 op }
123 06ceb376 2023-03-23 op
124 06ceb376 2023-03-23 op int
125 06ceb376 2023-03-23 op audio_flush(void)
126 06ceb376 2023-03-23 op {
127 06ceb376 2023-03-23 op stopped = 1;
128 06ceb376 2023-03-23 op return sio_flush(hdl);
129 06ceb376 2023-03-23 op }
130 06ceb376 2023-03-23 op
131 06ceb376 2023-03-23 op int
132 06ceb376 2023-03-23 op audio_stop(void)
133 06ceb376 2023-03-23 op {
134 06ceb376 2023-03-23 op stopped = 1;
135 06ceb376 2023-03-23 op return sio_stop(hdl);
136 06ceb376 2023-03-23 op }