xref: /openbsd/regress/lib/libsndio/rec/rec.c (revision 09467b48)
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <poll.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <sndio.h>
9 #include "tools.h"
10 
11 #define BUFSZ 0x1000
12 
13 void cb(void *, int);
14 void usage(void);
15 
16 unsigned char buf[BUFSZ];
17 struct sio_par par;
18 char *xstr[] = SIO_XSTRINGS;
19 
20 long long pos = 0;
21 int rlat = 0;
22 
23 void
24 cb(void *addr, int delta)
25 {
26 	pos += delta;
27 	rlat += delta;
28 	fprintf(stderr,
29 	    "cb: delta = %+7d, rlat = %+7d, pos = %+7lld\n",
30 	    delta, rlat, pos);
31 }
32 
33 void
34 usage(void) {
35 	fprintf(stderr, "usage: rec [-r rate] [-c nchan] [-e enc]\n");
36 }
37 
38 int
39 main(int argc, char **argv) {
40 	int ch;
41 	struct sio_hdl *hdl;
42 	ssize_t n;
43 
44 	/*
45 	 * defaults parameters
46 	 */
47 	sio_initpar(&par);
48 	par.sig = 1;
49 	par.bits = 16;
50 	par.rchan = 2;
51 	par.rate = 44100;
52 
53 	while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) {
54 		switch(ch) {
55 		case 'r':
56 			if (sscanf(optarg, "%u", &par.rate) != 1) {
57 				fprintf(stderr, "%s: bad rate\n", optarg);
58 				exit(1);
59 			}
60 			break;
61 		case 'c':
62 			if (sscanf(optarg, "%u", &par.rchan) != 1) {
63 				fprintf(stderr, "%s: channels number\n", optarg);
64 				exit(1);
65 			}
66 			break;
67 		case 'e':
68 			if (!sio_strtoenc(&par, optarg)) {
69 				fprintf(stderr, "%s: unknown encoding\n", optarg);
70 				exit(1);
71 			}
72 			break;
73 		case 'x':
74 			for (par.xrun = 0;; par.xrun++) {
75 				if (par.xrun == sizeof(xstr) / sizeof(char *)) {
76 					fprintf(stderr,
77 					    "%s: bad xrun mode\n", optarg);
78 					exit(1);
79 				}
80 				if (strcmp(xstr[par.xrun], optarg) == 0)
81 					break;
82 			}
83 			break;
84 		default:
85 			usage();
86 			exit(1);
87 			break;
88 		}
89 	}
90 
91 	hdl = sio_open(SIO_DEVANY, SIO_REC, 0);
92 	if (hdl == NULL) {
93 		fprintf(stderr, "sio_open() failed\n");
94 		exit(1);
95 	}
96 	sio_onmove(hdl, cb, NULL);
97 	if (!sio_setpar(hdl, &par)) {
98 		fprintf(stderr, "sio_setpar() failed\n");
99 		exit(1);
100 	}
101 	if (!sio_getpar(hdl, &par)) {
102 		fprintf(stderr, "sio_getpar() failed\n");
103 		exit(1);
104 	}
105 	if (!sio_start(hdl)) {
106 		fprintf(stderr, "sio_start() failed\n");
107 		exit(1);
108 	}
109 	for (;;) {
110 		n = sio_read(hdl, buf, BUFSZ);
111 		if (n == 0) {
112 			fprintf(stderr, "sio_write: failed\n");
113 			exit(1);
114 		}
115 		rlat -= n / (int)(par.bps * par.rchan);
116 		if (write(STDOUT_FILENO, buf, n) < 0) {
117 			perror("stdout");
118 			exit(1);
119 		}
120 	}
121 	sio_close(hdl);
122 	return 0;
123 }
124