1
0
mirror of https://github.com/openbsd/src.git synced 2025-01-10 06:47:55 -08:00

add a per-stream ``soft volume'' knob and the corresponding -v option.

The code will be useful later for the volume knob in the sndio API.
This commit is contained in:
ratchov 2008-11-10 23:25:37 +00:00
parent 7f96bf692c
commit 23be494310
9 changed files with 119 additions and 44 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: abuf.h,v 1.12 2008/11/09 16:26:07 ratchov Exp $ */
/* $OpenBSD: abuf.h,v 1.13 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -32,7 +32,8 @@ struct abuf {
* there can be only one aproc that absorbs xruns in any
* intput->output path.
*/
int mixivol; /* volume of the source stream */
int mixweight; /* volume of the source stream */
unsigned mixvol; /* volume in the range defined by wight */
unsigned mixodone; /* bytes done on the dest stream */
unsigned mixitodo; /* bytes to do on the source stream */
unsigned subidone; /* bytes copied from the source stream */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: aparams.c,v 1.3 2008/11/03 22:25:13 ratchov Exp $ */
/* $OpenBSD: aparams.c,v 1.4 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -21,6 +21,26 @@
#include "aparams.h"
int aparams_ctltovol[128] = {
0,
256, 266, 276, 287, 299, 310, 323, 335,
348, 362, 376, 391, 406, 422, 439, 456,
474, 493, 512, 532, 553, 575, 597, 621,
645, 670, 697, 724, 753, 782, 813, 845,
878, 912, 948, 985, 1024, 1064, 1106, 1149,
1195, 1241, 1290, 1341, 1393, 1448, 1505, 1564,
1625, 1689, 1756, 1825, 1896, 1971, 2048, 2128,
2212, 2299, 2389, 2483, 2580, 2682, 2787, 2896,
3010, 3128, 3251, 3379, 3511, 3649, 3792, 3941,
4096, 4257, 4424, 4598, 4778, 4966, 5161, 5363,
5574, 5793, 6020, 6256, 6502, 6757, 7023, 7298,
7585, 7883, 8192, 8514, 8848, 9195, 9556, 9931,
10321, 10726, 11148, 11585, 12040, 12513, 13004, 13515,
14045, 14596, 15170, 15765, 16384, 17027, 17696, 18390,
19112, 19863, 20643, 21453, 22295, 23170, 24080, 25025,
26008, 27029, 28090, 29193, 30339, 31530, 32768
};
/*
* Generate a string corresponding to the encoding in par,
* return the length of the resulting string

View File

@ -1,4 +1,4 @@
/* $OpenBSD: aparams.h,v 1.3 2008/11/03 22:25:13 ratchov Exp $ */
/* $OpenBSD: aparams.h,v 1.4 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -69,6 +69,11 @@ struct aparams {
#define ADATA_MAX (ADATA_UNIT - 1)
#define ADATA_MUL(x,y) (((x) * (y)) >> ADATA_SHIFT)
#define MIDI_MAXCTL 127
#define MIDI_TO_ADATA(m) (aparams_ctltovol[m])
extern int aparams_ctltovol[128];
void aparams_init(struct aparams *, unsigned, unsigned, unsigned);
void aparams_print(struct aparams *);
void aparams_print2(struct aparams *, struct aparams *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: aproc.c,v 1.22 2008/11/09 16:26:07 ratchov Exp $ */
/* $OpenBSD: aproc.c,v 1.23 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -350,9 +350,9 @@ void
mix_badd(struct abuf *ibuf, struct abuf *obuf)
{
short *idata, *odata;
int vol = ibuf->mixivol;
unsigned i, j, icnt, onext, ostart;
unsigned scount, icount, ocount;
int vol;
DPRINTFN(4, "mix_badd: todo = %u, done = %u\n",
obuf->mixitodo, ibuf->mixodone);
@ -367,6 +367,7 @@ mix_badd(struct abuf *ibuf, struct abuf *obuf)
if (ocount == 0)
return;
vol = (ibuf->mixweight * ibuf->mixvol) >> ADATA_SHIFT;
ostart = ibuf->cmin - obuf->cmin;
onext = obuf->cmax - ibuf->cmax + ostart;
icnt = ibuf->cmax - ibuf->cmin + 1;
@ -531,7 +532,8 @@ mix_newin(struct aproc *p, struct abuf *ibuf)
}
p->u.mix.idle = 0;
ibuf->mixodone = 0;
ibuf->mixivol = ADATA_UNIT;
ibuf->mixvol = ADATA_UNIT;
ibuf->mixweight = ADATA_UNIT;
ibuf->xrun = XRUN_IGNORE;
mix_setmaster(p);
}
@ -603,7 +605,7 @@ mix_setmaster(struct aproc *p)
LIST_FOREACH(buf, &p->ibuflist, ient)
n++;
LIST_FOREACH(buf, &p->ibuflist, ient)
buf->mixivol = ADATA_UNIT / n;
buf->mixweight = ADATA_UNIT / n;
}
void

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: aucat.1,v 1.29 2008/11/04 22:20:08 ratchov Exp $
.\" $OpenBSD: aucat.1,v 1.30 2008/11/10 23:25:37 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: November 4 2008 $
.Dd $Mdocdate: November 10 2008 $
.Dt AUCAT 1
.Os
.Sh NAME
@ -33,6 +33,7 @@
.Op Fl i Ar file
.Op Fl o Ar file
.Op Fl r Ar rate
.Op Fl v Ar volume
.Op Fl x Ar policy
.Ek
.Sh DESCRIPTION
@ -105,6 +106,10 @@ if this option is specified,
it will instead use the parameters specified by the
.Fl Ccer
options.
.It Fl v Ar volume
Software volume attenuation of the playback stream.
The value must be between 1 and 127,
corresponding to -42dB and -0dB attenuation.
.It Fl x Ar policy
Action when the output stream cannot accept
recorded data fast enough or the input stream

View File

@ -1,4 +1,4 @@
/* $OpenBSD: aucat.c,v 1.34 2008/11/09 16:26:07 ratchov Exp $ */
/* $OpenBSD: aucat.c,v 1.35 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -110,7 +110,8 @@ usage(void)
fprintf(stderr,
"usage: %s [-lu] [-b nsamples] [-C min:max] [-c min:max] [-e enc] "
"[-f device]\n"
"\t[-h fmt] [-i file] [-o file] [-r rate] [-x policy]\n",
"\t[-h fmt] [-i file] [-o file] [-r rate] [-v volume] "
"[-x policy]\n",
__progname);
}
@ -119,7 +120,7 @@ opt_ch(struct aparams *par)
{
if (sscanf(optarg, "%u:%u", &par->cmin, &par->cmax) != 2 ||
par->cmax < par->cmin || par->cmax > NCHAN_MAX - 1)
err(1, "%s: bad channel range", optarg);
errx(1, "%s: bad channel range", optarg);
}
void
@ -127,7 +128,15 @@ opt_rate(struct aparams *par)
{
if (sscanf(optarg, "%u", &par->rate) != 1 ||
par->rate < RATE_MIN || par->rate > RATE_MAX)
err(1, "%s: bad sample rate", optarg);
errx(1, "%s: bad sample rate", optarg);
}
void
opt_vol(unsigned *vol)
{
if (sscanf(optarg, "%u", vol) != 1 ||
*vol > MIDI_MAXCTL)
errx(1, "%s: bad volume", optarg);
}
void
@ -149,7 +158,7 @@ opt_hdr(void)
return HDR_RAW;
if (strcmp("wav", optarg) == 0)
return HDR_WAV;
err(1, "%s: bad header specification", optarg);
errx(1, "%s: bad header specification", optarg);
}
int
@ -244,6 +253,7 @@ newinput(struct farg *fa)
aproc_setout(proc, buf);
abuf_fill(buf); /* XXX: move this in dev_attach() ? */
dev_attach(fa->name, buf, &fa->par, fa->xrun, NULL, NULL, 0);
dev_setvol(buf, MIDI_TO_ADATA(fa->vol));
}
/*
@ -288,7 +298,7 @@ main(int argc, char **argv)
struct farglist ifiles, ofiles;
struct aparams ipar, opar, dipar, dopar;
struct sigaction sa;
unsigned ivol, ovol, bufsz;
unsigned ivol, bufsz;
char *devpath, *dbgenv, *listenpath;
const char *errstr;
extern char *malloc_options;
@ -311,10 +321,10 @@ main(int argc, char **argv)
SLIST_INIT(&ofiles);
hdr = HDR_AUTO;
xrun = XRUN_IGNORE;
ivol = ovol = MIDI_TO_ADATA(127);
ivol = MIDI_MAXCTL;
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) {
while ((c = getopt(argc, argv, "b:c:C:e:r:h:x:v:i:o:f:lu")) != -1) {
switch (c) {
case 'h':
hdr = opt_hdr();
@ -336,8 +346,11 @@ main(int argc, char **argv)
opt_rate(&ipar);
opar.rate = ipar.rate;
break;
case 'v':
opt_vol(&ivol);
break;
case 'i':
opt_file(&ifiles, &ipar, 127, hdr, xrun, optarg);
opt_file(&ifiles, &ipar, ivol, hdr, xrun, optarg);
break;
case 'o':
opt_file(&ofiles, &opar, 127, hdr, xrun, optarg);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: conf.h,v 1.4 2008/10/26 08:49:43 ratchov Exp $ */
/* $OpenBSD: conf.h,v 1.5 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -43,10 +43,6 @@ extern int debug_level;
#define DPRINTFN(n, ...) do {} while(0)
#endif
#define MIDI_MAXCTL 127
#define MIDI_TO_ADATA(m) ((ADATA_UNIT * (m) + 64) / 127)
/*
* number of blocks in the device play/record buffers. because Sun API
* cannot notify apps of the current positions, we have to use all N

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dev.c,v 1.13 2008/11/09 16:26:07 ratchov Exp $ */
/* $OpenBSD: dev.c,v 1.14 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -303,6 +303,41 @@ dev_stop(void)
dev_sub->u.sub.flags &= ~SUB_DROP;
}
/*
* find the end points connected to the mix/sub
*/
int
dev_getep(struct abuf **sibuf, struct abuf **sobuf)
{
struct abuf *ibuf, *obuf;
if (sibuf) {
ibuf = *sibuf;
for (;;) {
if (!ibuf || !ibuf->rproc) {
DPRINTF("dev_getep: reader desappeared\n");
return 0;
}
if (ibuf->rproc == dev_mix)
break;
ibuf = LIST_FIRST(&ibuf->rproc->obuflist);
}
}
if (sobuf) {
obuf = *sobuf;
for (;;) {
if (!obuf || !obuf->wproc) {
DPRINTF("dev_getep: writer desappeared\n");
return 0;
}
if (obuf->wproc == dev_sub)
break;
obuf = LIST_FIRST(&obuf->wproc->ibuflist);
}
}
return 1;
}
/*
* sync play buffer to rec buffer (for instance when one of
* them underruns/overruns)
@ -321,24 +356,8 @@ dev_sync(struct abuf *ibuf, struct abuf *obuf)
rbuf = LIST_FIRST(&dev_sub->ibuflist);
if (!rbuf)
return;
for (;;) {
if (!ibuf || !ibuf->rproc) {
DPRINTF("dev_sync: reader desappeared\n");
return;
}
if (ibuf->rproc == dev_mix)
break;
ibuf = LIST_FIRST(&ibuf->rproc->obuflist);
}
for (;;) {
if (!obuf || !obuf->wproc) {
DPRINTF("dev_sync: writer desappeared\n");
return;
}
if (obuf->wproc == dev_sub)
break;
obuf = LIST_FIRST(&obuf->wproc->ibuflist);
}
if (!dev_getep(&ibuf, &obuf))
return;
/*
* calculate delta, the number of frames the play chain is ahead
@ -475,6 +494,18 @@ dev_attach(char *name,
}
}
/*
* change the playback volume of the fiven stream
*/
void
dev_setvol(struct abuf *ibuf, int vol)
{
if (!dev_getep(&ibuf, NULL))
return;
fprintf(stderr, "vol = %d\n", vol);
ibuf->mixvol = vol;
}
/*
* clear buffers of the play and record chains so that when the device
* is started, playback and record start in sync

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dev.h,v 1.5 2008/11/09 16:26:07 ratchov Exp $ */
/* $OpenBSD: dev.h,v 1.6 2008/11/10 23:25:37 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@ -33,10 +33,12 @@ void dev_start(void);
void dev_stop(void);
void dev_run(int);
void dev_done(void);
int dev_getep(struct abuf **, struct abuf **);
void dev_sync(struct abuf *, struct abuf *);
void dev_attach(char *,
struct abuf *, struct aparams *, unsigned,
struct abuf *, struct aparams *, unsigned);
void dev_setvol(struct abuf *, int);
void dev_clear(void);
extern struct devops *devops, devops_sun, devops_aucat;