xref: /freebsd/share/examples/sound/kqueue.c (revision 6a569666868b36f5f436eea9d66789b6df191b8a)
1*6a569666SGoran Mekić /*
2*6a569666SGoran Mekić  * SPDX-License-Identifier: BSD-2-Clause
3*6a569666SGoran Mekić  *
4*6a569666SGoran Mekić  * Copyright (c) 2025 Goran Mekić
5*6a569666SGoran Mekić  *
6*6a569666SGoran Mekić  * Redistribution and use in source and binary forms, with or without
7*6a569666SGoran Mekić  * modification, are permitted provided that the following conditions
8*6a569666SGoran Mekić  * are met:
9*6a569666SGoran Mekić  * 1. Redistributions of source code must retain the above copyright
10*6a569666SGoran Mekić  *    notice, this list of conditions and the following disclaimer.
11*6a569666SGoran Mekić  * 2. Redistributions in binary form must reproduce the above copyright
12*6a569666SGoran Mekić  *    notice, this list of conditions and the following disclaimer in the
13*6a569666SGoran Mekić  *    documentation and/or other materials provided with the distribution.
14*6a569666SGoran Mekić  *
15*6a569666SGoran Mekić  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*6a569666SGoran Mekić  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*6a569666SGoran Mekić  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*6a569666SGoran Mekić  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*6a569666SGoran Mekić  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*6a569666SGoran Mekić  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*6a569666SGoran Mekić  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*6a569666SGoran Mekić  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*6a569666SGoran Mekić  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*6a569666SGoran Mekić  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*6a569666SGoran Mekić  * SUCH DAMAGE.
26*6a569666SGoran Mekić  */
27*6a569666SGoran Mekić 
28*6a569666SGoran Mekić #include <sys/event.h>
29*6a569666SGoran Mekić 
30*6a569666SGoran Mekić #include "oss.h"
31*6a569666SGoran Mekić 
32*6a569666SGoran Mekić int
main(int argc,char * argv[])33*6a569666SGoran Mekić main(int argc, char *argv[])
34*6a569666SGoran Mekić {
35*6a569666SGoran Mekić 	struct config config = {
36*6a569666SGoran Mekić 		.device = "/dev/dsp",
37*6a569666SGoran Mekić 		.mode = O_RDWR,
38*6a569666SGoran Mekić 		.format = AFMT_S32_NE,
39*6a569666SGoran Mekić 		.sample_rate = 48000,
40*6a569666SGoran Mekić 	};
41*6a569666SGoran Mekić 	struct kevent event = {};
42*6a569666SGoran Mekić 	int rc, bytes, kq;
43*6a569666SGoran Mekić 
44*6a569666SGoran Mekić 	oss_init(&config);
45*6a569666SGoran Mekić 	bytes = config.buffer_info.bytes;
46*6a569666SGoran Mekić 
47*6a569666SGoran Mekić 	if ((kq = kqueue()) < 0)
48*6a569666SGoran Mekić 		err(1, "Failed to allocate kqueue");
49*6a569666SGoran Mekić 	EV_SET(&event, config.fd, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, 0);
50*6a569666SGoran Mekić 	if (kevent(kq, &event, 1, NULL, 0, NULL) < 0)
51*6a569666SGoran Mekić 		err(1, "Failed to register kevent");
52*6a569666SGoran Mekić 	for (;;) {
53*6a569666SGoran Mekić 		if (kevent(kq, NULL, 0, &event, 1, NULL) < 0) {
54*6a569666SGoran Mekić 			warn("Event error");
55*6a569666SGoran Mekić 			break;
56*6a569666SGoran Mekić 		}
57*6a569666SGoran Mekić 		if (event.flags & EV_ERROR) {
58*6a569666SGoran Mekić 			warn("Event error: %s", strerror(event.data));
59*6a569666SGoran Mekić 			break;
60*6a569666SGoran Mekić 		}
61*6a569666SGoran Mekić 		if ((rc = read(config.fd, config.buf, bytes)) < bytes) {
62*6a569666SGoran Mekić 			warn("Requested %d bytes, but read %d!\n", bytes, rc);
63*6a569666SGoran Mekić 			break;
64*6a569666SGoran Mekić 		}
65*6a569666SGoran Mekić 		if ((rc = write(config.fd, config.buf, bytes)) < bytes) {
66*6a569666SGoran Mekić 			warn("Requested %d bytes, but wrote %d!\n", bytes, rc);
67*6a569666SGoran Mekić 			break;
68*6a569666SGoran Mekić 		}
69*6a569666SGoran Mekić 	}
70*6a569666SGoran Mekić 	EV_SET(&event, config.fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
71*6a569666SGoran Mekić 	if (kevent(kq, &event, 1, NULL, 0, NULL) < 0)
72*6a569666SGoran Mekić 		err(1, "Failed to unregister kevent");
73*6a569666SGoran Mekić 	close(kq);
74*6a569666SGoran Mekić 
75*6a569666SGoran Mekić 	free(config.buf);
76*6a569666SGoran Mekić 	close(config.fd);
77*6a569666SGoran Mekić 
78*6a569666SGoran Mekić 	return (0);
79*6a569666SGoran Mekić }
80