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