diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2008-11-07 21:01:16 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2008-11-07 21:01:16 +0000 |
commit | aec8d3abf216663cfafeba0fa3e1c84f7de452d3 (patch) | |
tree | f111daa0df7800e53fa065638c200e0334aa81bf /usr.bin | |
parent | 2644f1005720abae0bcf36faedaac6eb8ccfe601 (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.c | 3 | ||||
-rw-r--r-- | usr.bin/aucat/aucat.c | 13 | ||||
-rw-r--r-- | usr.bin/aucat/dev.c | 27 | ||||
-rw-r--r-- | usr.bin/aucat/dev.h | 4 | ||||
-rw-r--r-- | usr.bin/aucat/safile.c | 115 | ||||
-rw-r--r-- | usr.bin/aucat/safile.h | 4 |
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; |