summaryrefslogtreecommitdiff
path: root/regress/lib/libsndio/rec/rec.c
blob: e7d737e8d37400cd0811aafa6bd845cc37101d9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "sndio.h"

#define BUFSZ 0x1000
unsigned char buf[BUFSZ];
struct sio_par par;
char *xstr[] = SIO_XSTRINGS;

long long pos = 0;
int rlat = 0;

void
cb(void *addr, int delta)
{
	pos += delta;
	rlat += delta;
	fprintf(stderr,
	    "cb: delta = %+7d, rlat = %+7d, pos = %+7lld\n",
	    delta, rlat, pos);
}

void
usage(void) {
	fprintf(stderr, "usage: rec [-r rate] [-c nchan] [-e enc]\n");
}
 
int
main(int argc, char **argv) {
	int ch;
	struct sio_hdl *hdl;
	ssize_t n;
	
	/*
	 * defaults parameters
	 */
	sio_initpar(&par);
	par.sig = 1;
	par.bits = 16;
	par.rchan = 2;
	par.rate = 44100;
	par.bufsz = 0x10000;

	while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) {
		switch(ch) {
		case 'r':
			if (sscanf(optarg, "%u", &par.rate) != 1) {
				fprintf(stderr, "%s: bad rate\n", optarg);
				exit(1);
			}
			break;
		case 'c':
			if (sscanf(optarg, "%u", &par.rchan) != 1) {
				fprintf(stderr, "%s: channels number\n", optarg);
				exit(1);
			}
			break;
		case 'e':
			if (!sio_strtoenc(&par, optarg)) {
				fprintf(stderr, "%s: unknown encoding\n", optarg);
				exit(1);
			}
			break;
		case 'x':
			for (par.xrun = 0;; par.xrun++) {
				if (par.xrun == sizeof(xstr) / sizeof(char *)) {
					fprintf(stderr, 
					    "%s: bad xrun mode\n", optarg);
					exit(1);
				}
				if (strcmp(xstr[par.xrun], optarg) == 0)
					break;
			}
			break;			
		default:
			usage();
			exit(1);
			break;
		}
	}

	hdl = sio_open(NULL, SIO_REC, 0);
	if (hdl == NULL) {
		fprintf(stderr, "sio_open() failed\n");
		exit(1);
	}
	sio_onmove(hdl, cb, NULL);
	if (!sio_setpar(hdl, &par)) {
		fprintf(stderr, "sio_setpar() failed\n");
		exit(1);
	}
	if (!sio_getpar(hdl, &par)) {
		fprintf(stderr, "sio_getpar() failed\n");
		exit(1);
	}
	if (!sio_start(hdl)) {
		fprintf(stderr, "sio_start() failed\n");
		exit(1);
	}
	for (;;) {
		n = sio_read(hdl, buf, BUFSZ);
		if (n == 0) {
			fprintf(stderr, "sio_write: failed\n");
			exit(1);
		}
		rlat -= n / (int)(par.bps * par.rchan);
		if (write(STDOUT_FILENO, buf, n) < 0) {
			perror("stdout");
			exit(1);
		}
	}
	sio_close(hdl);
	return 0;
}