summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2008-11-07 21:01:16 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2008-11-07 21:01:16 +0000
commitaec8d3abf216663cfafeba0fa3e1c84f7de452d3 (patch)
treef111daa0df7800e53fa065638c200e0334aa81bf /usr.bin
parent2644f1005720abae0bcf36faedaac6eb8ccfe601 (diff)
expose the block size in the sndio API by making par->round writable
and thus remove the ugly rate <-> block-size table from sio_setpar(3). Handle the block size negociation in aucat(1), since it has few constrains the code is overally simpler. ok jakemsr@, major crank suggested by deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/aucat/aproc.c3
-rw-r--r--usr.bin/aucat/aucat.c13
-rw-r--r--usr.bin/aucat/dev.c27
-rw-r--r--usr.bin/aucat/dev.h4
-rw-r--r--usr.bin/aucat/safile.c115
-rw-r--r--usr.bin/aucat/safile.h4
6 files changed, 136 insertions, 30 deletions
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c
index 1c70ab340f2..c21b481402e 100644
--- a/usr.bin/aucat/aproc.c
+++ b/usr.bin/aucat/aproc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.c,v 1.20 2008/11/06 17:47:52 ratchov Exp $ */
+/* $OpenBSD: aproc.c,v 1.21 2008/11/07 21:01:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -534,6 +534,7 @@ mix_newin(struct aproc *p, struct abuf *ibuf)
void
mix_newout(struct aproc *p, struct abuf *obuf)
{
+ DPRINTF("mix_newout: using %u fpb\n", obuf->len / obuf->bpf);
obuf->mixitodo = 0;
mix_bzero(p);
}
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index 5e41f46c65a..b41b43770cf 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.31 2008/11/03 22:25:13 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.32 2008/11/07 21:01:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -288,7 +288,7 @@ main(int argc, char **argv)
struct farglist ifiles, ofiles;
struct aparams ipar, opar, dipar, dopar;
struct sigaction sa;
- unsigned ivol, ovol, bufsz = 0;
+ unsigned ivol, ovol, bufsz;
char *devpath, *dbgenv, *listenpath;
const char *errstr;
extern char *malloc_options;
@@ -304,7 +304,6 @@ main(int argc, char **argv)
aparams_init(&ipar, 0, 1, 44100);
aparams_init(&opar, 0, 1, 44100);
-
u_flag = 0;
l_flag = 0;
devpath = NULL;
@@ -313,6 +312,7 @@ main(int argc, char **argv)
hdr = HDR_AUTO;
xrun = XRUN_IGNORE;
ivol = ovol = MIDI_TO_ADATA(127);
+ bufsz = 44100 * 4 / 15; /* XXX: use milliseconds, not frames */
while ((c = getopt(argc, argv, "b:c:C:e:r:h:x:i:o:f:lu"))
!= -1) {
@@ -357,7 +357,7 @@ main(int argc, char **argv)
u_flag = 1;
break;
case 'b':
- if (sscanf(optarg, "%u", &bufsz) != 1) {
+ if (sscanf(optarg, "%u", &bufsz) != 1 || bufsz == 0) {
fprintf(stderr, "%s: bad buf size\n", optarg);
exit(1);
}
@@ -438,12 +438,13 @@ main(int argc, char **argv)
filelist_init();
/*
- * Open the device.
+ * Open the device. Give half of the buffer to the device,
+ * the other half is for the socket/files
*/
dev_init(devpath,
(l_flag || !SLIST_EMPTY(&ofiles)) ? &dipar : NULL,
(l_flag || !SLIST_EMPTY(&ifiles)) ? &dopar : NULL,
- bufsz);
+ bufsz, l_flag);
if (l_flag) {
listenpath = getenv("AUCAT_SOCKET");
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index 17e09c9c0a4..91df14b062b 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.10 2008/11/07 00:21:02 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.11 2008/11/07 21:01:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -94,7 +94,8 @@ dev_roundrate(unsigned *newrate, unsigned *newround)
*/
void
dev_init(char *devpath,
- struct aparams *dipar, struct aparams *dopar, unsigned bufsz)
+ struct aparams *dipar, struct aparams *dopar,
+ unsigned bufsz, int blkio)
{
struct aparams ipar, opar;
struct aproc *conv;
@@ -102,11 +103,13 @@ dev_init(char *devpath,
unsigned nfr, ibufsz, obufsz;
/*
- * use 1/4 of the total buffer for the device
+ * ask for 1/4 of the buffer for the kernel ring and
+ * limit the block size to 1/4 of the requested buffer
*/
dev_bufsz = (bufsz + 3) / 4;
+ dev_round = (bufsz + 3) / 4;
dev_file = (struct file *)safile_new(&safile_ops, devpath,
- dipar, dopar, &dev_bufsz, &dev_round);
+ dipar, dopar, &dev_bufsz, &dev_round, blkio);
if (!dev_file)
exit(1);
if (!dev_setrate(dipar ? dipar->rate : dopar->rate))
@@ -127,10 +130,22 @@ dev_init(char *devpath,
fprintf(stderr, "\n");
}
}
- nfr = ibufsz = obufsz = dev_bufsz;
+ ibufsz = obufsz = dev_bufsz;
+ bufsz = (bufsz > dev_bufsz) ? bufsz - dev_bufsz : 0;
/*
- * create record chain: use 1/4 for the file i/o buffers
+ * use 1/8 of the buffer for the mixer/converters. Since we
+ * already consumed 1/4 for the device, bufsz represents the
+ * remaining 3/4. So 1/8 is 1/6 of 3/4
+ */
+ nfr = (bufsz + 5) / 6;
+ nfr += dev_round - 1;
+ nfr -= nfr % dev_round;
+ if (nfr == 0)
+ nfr = dev_round;
+
+ /*
+ * create record chain
*/
if (dipar) {
aparams_init(&ipar, dipar->cmin, dipar->cmax, dipar->rate);
diff --git a/usr.bin/aucat/dev.h b/usr.bin/aucat/dev.h
index b23fd9e1561..7e11bdca93d 100644
--- a/usr.bin/aucat/dev.h
+++ b/usr.bin/aucat/dev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.h,v 1.3 2008/10/26 08:49:43 ratchov Exp $ */
+/* $OpenBSD: dev.h,v 1.4 2008/11/07 21:01:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -28,7 +28,7 @@ extern struct aparams dev_ipar, dev_opar;
extern struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play;
void dev_roundrate(unsigned *, unsigned *);
-void dev_init(char *, struct aparams *, struct aparams *, unsigned);
+void dev_init(char *, struct aparams *, struct aparams *, unsigned, int);
void dev_start(void);
void dev_stop(void);
void dev_run(int);
diff --git a/usr.bin/aucat/safile.c b/usr.bin/aucat/safile.c
index d0a8697b530..5d60f99ab02 100644
--- a/usr.bin/aucat/safile.c
+++ b/usr.bin/aucat/safile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: safile.c,v 1.2 2008/10/27 00:26:33 ratchov Exp $ */
+/* $OpenBSD: safile.c,v 1.3 2008/11/07 21:01:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -49,7 +49,7 @@ int safile_pollfd(struct file *, struct pollfd *, int);
int safile_revents(struct file *, struct pollfd *);
struct fileops safile_ops = {
- "libsndsio",
+ "sndio",
sizeof(struct safile),
safile_close,
safile_read,
@@ -61,6 +61,101 @@ struct fileops safile_ops = {
safile_revents
};
+/*
+ * list of (rate, block-size) pairs ordered by frequency preference and
+ * then by block size preference (except for jumbo block sizes that are
+ * less prefered than anything else).
+ */
+struct blkdesc {
+ unsigned rate; /* sample rate */
+ unsigned round; /* usable block sizes */
+} blkdesc[] = {
+ { 44100, 882 },
+ { 44100, 840 },
+ { 44100, 441 },
+ { 44100, 420 },
+ { 44100, 1764 },
+ { 44100, 1680 },
+ { 48000, 960 },
+ { 48000, 768 },
+ { 48000, 480 },
+ { 48000, 384 },
+ { 48000, 1920 },
+ { 48000, 1536 },
+ { 32000, 640 },
+ { 32000, 512 },
+ { 32000, 320 },
+ { 32000, 256 },
+ { 32000, 1280 },
+ { 32000, 1024 },
+ { 44100, 2940 },
+ { 48000, 2976 },
+ { 32000, 3200 },
+ { 8000, 320 },
+ { 8000, 256 },
+ { 0, 0 }
+};
+
+
+int
+safile_trypar(struct sio_hdl *hdl, struct sio_par *par, int blkio)
+{
+ struct blkdesc *d;
+ struct sio_par np;
+ unsigned rate = par->rate;
+ unsigned round = par->round;
+
+ if (!blkio) {
+ fprintf(stderr, "not setting block size\n");
+ if (!sio_setpar(hdl, par))
+ return 0;
+ if (!sio_getpar(hdl, par))
+ return 0;
+ return 1;
+ }
+
+ /*
+ * find the rate we want to use
+ */
+ for (d = blkdesc;; d++) {
+ if (d->rate == 0) {
+ d = blkdesc;
+ break;
+ }
+ if (d->rate == rate)
+ break;
+ }
+
+ /*
+ * find the first matching entry, (the blkdesc array is)
+ * sorted by order of preference)
+ */
+ for (;; d++) {
+ if (d->rate == 0)
+ break;
+ if (d->round > round)
+ continue;
+ par->rate = d->rate;
+ par->round = d->round;
+ if (!sio_setpar(hdl, par))
+ return 0;
+ if (!sio_getpar(hdl, &np))
+ return 0;
+ if (np.rate == d->rate && np.round == d->round) {
+ *par = np;
+ if (d->round >= d->rate / 15)
+ fprintf(stderr,
+ "Warning: using jumbo block size, "
+ "try to use another sample rate.\n");
+ return 1;
+ }
+ DPRINTF("safile_trypar: %uHz/%ufr failed, got %uHz/%ufr\n",
+ d->rate, d->round, np.rate, np.round);
+ }
+ fprintf(stderr, "Couldn't set block size to <%u frames.\n", round);
+ return 0;
+}
+
void
safile_cb(void *addr, int delta)
{
@@ -85,7 +180,7 @@ safile_cb(void *addr, int delta)
struct safile *
safile_new(struct fileops *ops, char *path,
struct aparams *ipar, struct aparams *opar,
- unsigned *bufsz, unsigned *round)
+ unsigned *bufsz, unsigned *round, int blkio)
{
struct sio_par par;
struct sio_hdl *hdl;
@@ -123,16 +218,10 @@ safile_new(struct fileops *ops, char *path,
}
if (opar)
par.pchan = opar->cmax - opar->cmin + 1;
- if (*bufsz)
- par.bufsz = *bufsz;
- if (!sio_setpar(hdl, &par)) {
- fprintf(stderr, "safile_new: sio_setpar failed\n");
+ par.bufsz = *bufsz;
+ par.round = *round;
+ if (!safile_trypar(hdl, &par, blkio))
exit(1);
- }
- if (!sio_getpar(hdl, &par)) {
- fprintf(stderr, "safile_new: sio_getpar failed\n");
- exit(1);
- }
if (ipar) {
ipar->bits = par.bits;
ipar->bps = par.bps;
@@ -155,7 +244,7 @@ safile_new(struct fileops *ops, char *path,
}
*bufsz = par.bufsz;
*round = par.round;
- DPRINTF("safile_open: using %u(%u) fpb\n", *bufsz, *round);
+ DPRINTF("safile_new: using %u(%u) fpb\n", *bufsz, *round);
f = (struct safile *)file_new(ops, "hdl", sio_nfds(hdl));
f->hdl = hdl;
sio_onmove(f->hdl, safile_cb, f);
diff --git a/usr.bin/aucat/safile.h b/usr.bin/aucat/safile.h
index 328e9863531..ff1eb65eb6e 100644
--- a/usr.bin/aucat/safile.h
+++ b/usr.bin/aucat/safile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: safile.h,v 1.1 2008/10/26 08:49:44 ratchov Exp $ */
+/* $OpenBSD: safile.h,v 1.2 2008/11/07 21:01:15 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -23,7 +23,7 @@ struct safile;
struct aparams;
struct safile *safile_new(struct fileops *, char *,
- struct aparams *, struct aparams *, unsigned *, unsigned *);
+ struct aparams *, struct aparams *, unsigned *, unsigned *, int);
extern struct fileops safile_ops;