sndio/examples/rec.c

147 lines
2.7 KiB
C
Raw Normal View History

2011-05-07 07:08:45 -05:00
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sndio.h>
#include "tools.h"
2013-11-18 10:50:04 -06:00
void cb(void *, int);
void usage(void);
2013-12-31 06:15:06 -06:00
unsigned char *buf;
2011-05-07 07:08:45 -05:00
struct sio_par par;
char *xstr[] = SIO_XSTRINGS;
2014-11-18 02:43:12 -06:00
unsigned long long recpos = 0, readpos = 0;
2013-12-31 06:15:06 -06:00
int tick = 0;
2011-05-07 07:08:45 -05:00
void
cb(void *addr, int delta)
{
2014-11-18 02:43:12 -06:00
unsigned int bytes;
2013-12-31 06:15:06 -06:00
2014-11-18 02:43:12 -06:00
bytes = delta * par.bps * par.rchan;
2013-12-31 06:15:06 -06:00
// fprintf(stderr, "advanced by %d\n", bytes);
recpos += bytes;
tick = 1;
2011-05-07 07:08:45 -05:00
}
void
2013-12-31 06:15:06 -06:00
usage(void)
{
fprintf(stderr,
"usage: rec [-b size] [-c nchan] [-e enc] [-r rate]\n");
2011-05-07 07:08:45 -05:00
}
2013-12-31 06:15:06 -06:00
2011-05-07 07:08:45 -05:00
int
2013-12-31 06:15:06 -06:00
main(int argc, char **argv)
{
2011-05-07 07:08:45 -05:00
int ch;
struct sio_hdl *hdl;
2013-12-31 06:15:06 -06:00
size_t bufsz;
2011-05-07 07:08:45 -05:00
ssize_t n;
/*
* defaults parameters
*/
sio_initpar(&par);
par.sig = 1;
par.bits = 16;
par.rchan = 2;
2013-12-31 06:15:06 -06:00
par.rate = 48000;
2011-05-07 07:08:45 -05:00
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 (!strtoenc(&par, optarg)) {
2011-05-07 07:08:45 -05:00
fprintf(stderr, "%s: unknown encoding\n", optarg);
exit(1);
}
break;
2014-02-13 05:36:43 -06:00
case 'b':
if (sscanf(optarg, "%u", &par.appbufsz) != 1) {
fprintf(stderr, "%s: bad buf size\n", optarg);
exit(1);
}
break;
2011-05-07 07:08:45 -05:00
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;
}
}
2012-05-23 14:26:54 -05:00
hdl = sio_open(SIO_DEVANY, SIO_REC, 0);
2011-05-07 07:08:45 -05:00
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);
}
2013-12-31 06:15:06 -06:00
bufsz = par.bps * par.rchan * par.round;
buf = malloc(bufsz);
if (buf == NULL) {
fprintf(stderr, "failed to allocate %zu bytes\n", bufsz);
exit(1);
}
fprintf(stderr, "%zu bytes buffer, max latency %u frames\n",
bufsz, par.bufsz);
2011-05-07 07:08:45 -05:00
if (!sio_start(hdl)) {
fprintf(stderr, "sio_start() failed\n");
exit(1);
}
for (;;) {
2013-12-31 06:15:06 -06:00
n = sio_read(hdl, buf, bufsz);
2011-05-07 07:08:45 -05:00
if (n == 0) {
fprintf(stderr, "sio_write: failed\n");
exit(1);
}
2013-12-31 06:15:06 -06:00
readpos += n;
if (tick) {
fprintf(stderr,
2013-12-31 06:34:04 -06:00
"recpos = %lld, readpos = %lld, latency = %lld\n",
2013-12-31 06:15:06 -06:00
recpos, readpos, recpos - readpos);
tick = 0;
}
2011-05-07 07:08:45 -05:00
if (write(STDOUT_FILENO, buf, n) < 0) {
perror("stdout");
exit(1);
}
}
sio_close(hdl);
return 0;
}