diff options
Diffstat (limited to 'regress/lib/libsndio')
-rw-r--r-- | regress/lib/libsndio/Makefile | 5 | ||||
-rw-r--r-- | regress/lib/libsndio/cap/Makefile | 6 | ||||
-rw-r--r-- | regress/lib/libsndio/cap/cap.c | 97 | ||||
-rw-r--r-- | regress/lib/libsndio/fd/Makefile | 6 | ||||
-rw-r--r-- | regress/lib/libsndio/fd/fd.c | 363 | ||||
-rw-r--r-- | regress/lib/libsndio/play/Makefile | 6 | ||||
-rw-r--r-- | regress/lib/libsndio/play/play.c | 133 | ||||
-rw-r--r-- | regress/lib/libsndio/rec/Makefile | 6 | ||||
-rw-r--r-- | regress/lib/libsndio/rec/rec.c | 119 |
9 files changed, 741 insertions, 0 deletions
diff --git a/regress/lib/libsndio/Makefile b/regress/lib/libsndio/Makefile new file mode 100644 index 00000000000..f5f394dc7e3 --- /dev/null +++ b/regress/lib/libsndio/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2008/10/27 00:26:33 ratchov Exp $ + +SUBDIR+= play rec fd cap + +.include <bsd.subdir.mk> diff --git a/regress/lib/libsndio/cap/Makefile b/regress/lib/libsndio/cap/Makefile new file mode 100644 index 00000000000..141d859367b --- /dev/null +++ b/regress/lib/libsndio/cap/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2008/10/27 00:26:33 ratchov Exp $ +PROG= cap +LDADD= -lsndio +REGRESS_SKIP= + +.include <bsd.regress.mk> diff --git a/regress/lib/libsndio/cap/cap.c b/regress/lib/libsndio/cap/cap.c new file mode 100644 index 00000000000..3933bcd4da7 --- /dev/null +++ b/regress/lib/libsndio/cap/cap.c @@ -0,0 +1,97 @@ +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sndio.h> + +struct sio_par par; +struct sio_cap cap; + +void +pr_enc(struct sio_enc *enc) +{ + fprintf(stderr, "%s%d", enc->sig ? "s" : "u", enc->bits); + if (enc->bps > 1) + fprintf(stderr, "%s", enc->le ? "le" : "be"); + if (enc->bps != SIO_BPS(enc->bits)) + fprintf(stderr, "%d%s", enc->bps, enc->msb ? "msb" : "lsb"); +} + +void +cap_pr(struct sio_cap *cap) +{ + unsigned n, i; + + for (n = 0; n < cap->nconf; n++) { + fprintf(stderr, "config %d\n", n); + fprintf(stderr, "\tenc:"); + for (i = 0; i < SIO_NENC; i++) { + if (cap->confs[n].enc & (1 << i)) { + fprintf(stderr, " "); + pr_enc(&cap->enc[i]); + } + } + fprintf(stderr, "\n\tpchan:"); + for (i = 0; i < SIO_NCHAN; i++) { + if (cap->confs[n].pchan & (1 << i)) + fprintf(stderr, " %d", cap->pchan[i]); + } + fprintf(stderr, "\n\trchan:"); + for (i = 0; i < SIO_NCHAN; i++) { + if (cap->confs[n].rchan & (1 << i)) + fprintf(stderr, " %d", cap->rchan[i]); + } + fprintf(stderr, "\n\trate:"); + for (i = 0; i < SIO_NRATE; i++) { + if (cap->confs[n].rate & (1 << i)) + fprintf(stderr, " %d", cap->rate[i]); + } + fprintf(stderr, "\n"); + } +} + +void +usage(void) { + fprintf(stderr, "usage: cap [-pr]\n"); +} + +int +main(int argc, char **argv) { + int ch; + unsigned mode = SIO_PLAY | SIO_REC; + struct sio_hdl *hdl; + + while ((ch = getopt(argc, argv, "pr")) != -1) { + switch(ch) { + case 'p': + mode &= ~SIO_REC; + break; + case 'r': + mode &= ~SIO_PLAY; + break; + default: + usage(); + exit(1); + break; + } + } + if (mode == 0) { + fprintf(stderr, "-p and -r flags are mutualy exclusive\n"); + exit(1); + } + hdl = sio_open(NULL, mode, 0); + if (hdl == NULL) { + fprintf(stderr, "sio_open() failed\n"); + exit(1); + } + if (!sio_getcap(hdl, &cap)) { + fprintf(stderr, "sio_setcap() failed\n"); + exit(1); + } + cap_pr(&cap); + sio_close(hdl); + return 0; +} diff --git a/regress/lib/libsndio/fd/Makefile b/regress/lib/libsndio/fd/Makefile new file mode 100644 index 00000000000..431850655cd --- /dev/null +++ b/regress/lib/libsndio/fd/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2008/10/27 00:26:33 ratchov Exp $ +PROG= fd +LDADD= -lsndio +REGRESS_SKIP= + +.include <bsd.regress.mk> diff --git a/regress/lib/libsndio/fd/fd.c b/regress/lib/libsndio/fd/fd.c new file mode 100644 index 00000000000..9a76946bc55 --- /dev/null +++ b/regress/lib/libsndio/fd/fd.c @@ -0,0 +1,363 @@ +#include <sys/time.h> +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sndio.h> + +struct buf { /* simple circular fifo */ + unsigned start; /* first used byte */ + unsigned used; /* number of used bytes */ +#define BUF_LEN (240 * 0x1000) /* i/o buffer size */ + unsigned char data[BUF_LEN]; +}; + +char *xstr[] = SIO_XSTRINGS; +struct sio_par par; +struct buf playbuf, recbuf; + +long long pos = 0; +int plat = 0, rlat = 0; + +void +cb(void *addr, int delta) +{ + pos += delta; + fprintf(stderr, "cb: delta = %+7d, pos = %+7lld, " + "plat = %+7d, rlat = %+7d\n", + delta, pos, plat, rlat); + plat -= delta; + rlat += delta; +} + +/* + * read buffer contents from a file without blocking + */ +void +buf_read(struct buf *buf, int fd) { + unsigned count, end, avail; + int n; + + for (;;) { + avail = BUF_LEN - buf->used; + if (avail == 0) + break; + end = buf->start + buf->used; + if (end >= BUF_LEN) + end -= BUF_LEN; + count = BUF_LEN - end; + if (count > avail) + count = avail; + n = read(fd, buf->data + end, count); + if (n < 0) { + perror("buf_read: read"); + exit(1); + } + if (n == 0) { + bzero(buf->data + end, count); + n = count; + } + buf->used += n; + } +} + +/* + * write buffer contents to file, without blocking + */ +void +buf_write(struct buf *buf, int fd) +{ + unsigned count; + int n; + + while (buf->used) { + count = BUF_LEN - buf->start; + if (count > buf->used) + count = buf->used; + n = write(fd, buf->data + buf->start, count); + if (n < 0) { + perror("buf_write: write"); + exit(1); + } + buf->used -= n; + buf->start += n; + if (buf->start >= BUF_LEN) + buf->start -= BUF_LEN; + } +} + +/* + * read buffer contents from a file without blocking + */ +unsigned +buf_rec(struct buf *buf, struct sio_hdl *hdl) +{ + unsigned count, end, avail, done = 0; + int bpf = par.rchan * par.bps; + int n; + + for (;;) { + avail = BUF_LEN - buf->used; + if (avail == 0) + break; + end = buf->start + buf->used; + if (end >= BUF_LEN) + end -= BUF_LEN; + count = BUF_LEN - end; + if (count > avail) + count = avail; + n = sio_read(hdl, buf->data + end, count); + if (n == 0) { + if (sio_eof(hdl)) { + fprintf(stderr, "sio_read() failed\n"); + exit(1); + } + break; + } + if (n % bpf) { + fprintf(stderr, "rec: bad align: %u bytes\n", n); + exit(1); + } + rlat -= n / bpf; + buf->used += n; + done += n; + } + return done; +} + +/* + * write buffer contents to file, without blocking + */ +unsigned +buf_play(struct buf *buf, struct sio_hdl *hdl) +{ + unsigned count, done = 0; + int bpf = par.pchan * par.bps; + int n; + + while (buf->used) { + count = BUF_LEN - buf->start; + if (count > buf->used) + count = buf->used; + /* try to confuse the server */ + //count = 1 + (rand() % count); + n = sio_write(hdl, buf->data + buf->start, count); + if (n == 0) { + if (sio_eof(hdl)) { + fprintf(stderr, "sio_write() failed\n"); + exit(1); + } + break; + } + if (n % bpf) { + fprintf(stderr, "play: bad align: %u bytes\n", n); + exit(1); + } + plat += n / bpf; + //write(STDOUT_FILENO, buf->data + buf->start, n); + buf->used -= n; + buf->start += n; + if (buf->start >= BUF_LEN) + buf->start -= BUF_LEN; + done += n; + } + return done; +} + +void +usage(void) { + fprintf(stderr, + "usage: fd [-v] [-r rate] [-c ichan] [-C ochan] [-e enc] " + "[-i file] [-o file]\n"); +} + +int +main(int argc, char **argv) { + int ch, recfd, playfd, events, revents; + char *recpath, *playpath; + struct sio_hdl *hdl; + struct pollfd pfd; + struct timeval tv, otv, ntv; + unsigned mode, done; + + recpath = NULL; + playpath = NULL; + + /* + * defaults parameters + */ + sio_initpar(&par); + par.sig = 1; + par.bits = 16; + par.pchan = par.rchan = 2; + par.rate = 44100; + + while ((ch = getopt(argc, argv, "r:c:C:e:i:o: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.pchan) != 1) { + fprintf(stderr, "%s: bad play chans\n", optarg); + exit(1); + } + break; + case 'C': + if (sscanf(optarg, "%u", &par.rchan) != 1) { + fprintf(stderr, "%s: bad rec chans\n", optarg); + exit(1); + } + break; + case 'e': + if (!sio_strtoenc(&par, optarg)) { + fprintf(stderr, "%s: unknown encoding\n", optarg); + exit(1); + } + break; + case 'o': + recpath = optarg; + break; + case 'i': + playpath = optarg; + break; + case 'b': + if (sscanf(optarg, "%u", &par.bufsz) != 1) { + fprintf(stderr, "%s: bad buf size\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; + } + } + mode = 0; + if (recpath) + mode |= SIO_REC; + if (playpath) + mode |= SIO_PLAY; + if (mode == 0) { + fprintf(stderr, "-i or -o option required\n"); + exit(0); + } + hdl = sio_open(NULL, mode, 1); + 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_setpar() failed\n"); + exit(1); + } + fprintf(stderr, "using %u%%%u frame buffer\n", par.bufsz, par.round); + if (!sio_start(hdl)) { + fprintf(stderr, "sio_start() failed\n"); + exit(1); + } + + events = 0; + if (recpath > 0) { + recfd = open(recpath, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (recfd < 0) { + perror(recpath); + exit(1); + } + events |= POLLIN; + } + if (playpath > 0) { + playfd = open(playpath, O_RDONLY, 0); + if (playfd < 0) { + perror(playpath); + exit(1); + } + events |= POLLOUT; + buf_read(&playbuf, playfd); + buf_play(&playbuf, hdl); + } + gettimeofday(&otv, NULL); + for (;;) { + gettimeofday(&ntv, NULL); + timersub(&ntv, &otv, &tv); +#if 0 /* trigger underrun */ + if (playpath && (tv.tv_sec % 10) < 7) { + events |= POLLOUT; + } else + events &= ~POLLOUT; +#endif +#if 0 /* trigger overrun */ + if (recpath && (tv.tv_sec % 10) < 7) { + events |= POLLIN; + } else + events &= ~POLLIN; +#endif + //fprintf(stderr, "%ld.%06ld: polling for %d\n", + // tv.tv_sec, tv.tv_usec, events); + sio_pollfd(hdl, &pfd, events); + while (poll(&pfd, 1, 1000) < 0) { + if (errno == EINTR) + continue; + perror("poll"); + exit(1); + } + revents = sio_revents(hdl, &pfd); + gettimeofday(&ntv, NULL); + timersub(&ntv, &otv, &tv); + //fprintf(stderr, "%ld.%06ld: got %d\n", + // tv.tv_sec, tv.tv_usec, revents); + if (revents & POLLHUP) { + fprintf(stderr, "device hangup\n"); + exit(0); + } + if (revents & POLLIN) { + done = buf_rec(&recbuf, hdl); + buf_write(&recbuf, recfd); + //fprintf(stderr, "%ld.%06ld: recored %u\n", + // tv.tv_sec, tv.tv_usec, done); + } + if (revents & POLLOUT) { + done = buf_play(&playbuf, hdl); + buf_read(&playbuf, playfd); + } +#if 0 + if (pos / par.rate > 2) { + if (!sio_stop(hdl)) { + fprintf(stderr, "sio_stop failed\n"); + exit(1); + } + pos = plat = rlat = 0; + fprintf(stderr, "pausing...\n"); + sleep(1); + if (!sio_start(hdl)) { + fprintf(stderr, "sio_start failed\n"); + exit(1); + } + } +#endif + } + sio_close(hdl); + return 0; +} diff --git a/regress/lib/libsndio/play/Makefile b/regress/lib/libsndio/play/Makefile new file mode 100644 index 00000000000..5e2f2020ea0 --- /dev/null +++ b/regress/lib/libsndio/play/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2008/10/27 00:26:33 ratchov Exp $ +PROG= play +LDADD= -lsndio +REGRESS_SKIP= + +.include <bsd.regress.mk> diff --git a/regress/lib/libsndio/play/play.c b/regress/lib/libsndio/play/play.c new file mode 100644 index 00000000000..a3b28b42ba3 --- /dev/null +++ b/regress/lib/libsndio/play/play.c @@ -0,0 +1,133 @@ +#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 0x100 +unsigned char buf[BUFSZ]; +struct sio_par par; +char *xstr[] = SIO_XSTRINGS; + +long long realpos = 0, playpos = 0; + +void +cb(void *addr, int delta) +{ + int bytes = delta * (int)(par.bps * par.pchan); + + realpos += bytes; + + fprintf(stderr, + "cb: bytes = %+7d, latency = %+7lld, " + "realpos = %+7lld, bufused = %+7lld\n", + bytes, playpos - realpos, + realpos, (realpos < 0) ? playpos : playpos - realpos); +} + +void +usage(void) { + fprintf(stderr, "usage: play [-r rate] [-c nchan] [-e enc]\n"); +} + +int +main(int argc, char **argv) { + int ch; + struct sio_hdl *hdl; + ssize_t n, len; + + /* + * defaults parameters + */ + sio_initpar(&par); + par.sig = 1; + par.bits = 16; + par.pchan = 2; + par.rate = 44100; + + 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.pchan) != 1) { + fprintf(stderr, "%s: bad channels\n", optarg); + exit(1); + } + break; + case 'e': + if (!sio_strtoenc(&par, optarg)) { + fprintf(stderr, "%s: bad encoding\n", optarg); + exit(1); + } + break; + case 'b': + if (sscanf(optarg, "%u", &par.bufsz) != 1) { + fprintf(stderr, "%s: bad buf size\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_PLAY, 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); + } + fprintf(stderr, "using %u bytes per buffer, rounding to %u\n", + par.bufsz * par.bps * par.pchan, + par.round * par.bps * par.pchan); + for (;;) { + len = read(STDIN_FILENO, buf, BUFSZ); + if (len < 0) { + perror("stdin"); + exit(1); + } + if (len == 0) + break; + n = sio_write(hdl, buf, len); + if (n == 0) { + fprintf(stderr, "sio_write: failed\n"); + exit(1); + } + playpos += n; + } + sio_close(hdl); + return 0; +} diff --git a/regress/lib/libsndio/rec/Makefile b/regress/lib/libsndio/rec/Makefile new file mode 100644 index 00000000000..773e9789f26 --- /dev/null +++ b/regress/lib/libsndio/rec/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2008/10/27 00:26:33 ratchov Exp $ +PROG= rec +LDADD= -lsndio +REGRESS_SKIP= + +.include <bsd.regress.mk> diff --git a/regress/lib/libsndio/rec/rec.c b/regress/lib/libsndio/rec/rec.c new file mode 100644 index 00000000000..e7d737e8d37 --- /dev/null +++ b/regress/lib/libsndio/rec/rec.c @@ -0,0 +1,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; +} |