add -w option to switch off automatic volume adjustments

This commit is contained in:
Alexandre Ratchov 2011-05-13 13:38:34 +02:00
parent a6816c6fa5
commit 02f3853786
6 changed files with 41 additions and 11 deletions

View File

@ -1016,7 +1016,7 @@ struct aproc_ops mix_ops = {
}; };
struct aproc * struct aproc *
mix_new(char *name, int maxlat, unsigned round) mix_new(char *name, int maxlat, unsigned round, unsigned autovol)
{ {
struct aproc *p; struct aproc *p;
@ -1027,6 +1027,7 @@ mix_new(char *name, int maxlat, unsigned round)
p->u.mix.maxlat = maxlat; p->u.mix.maxlat = maxlat;
p->u.mix.ctl = NULL; p->u.mix.ctl = NULL;
p->u.mix.mon = NULL; p->u.mix.mon = NULL;
p->u.mix.autovol = autovol;
return p; return p;
} }
@ -1040,6 +1041,9 @@ mix_setmaster(struct aproc *p)
struct abuf *i, *j; struct abuf *i, *j;
int weight; int weight;
if (!p->u.mix.autovol)
return;
/* /*
* count the number of inputs. If a set of inputs * count the number of inputs. If a set of inputs
* uses channels that have no intersection, they are * uses channels that have no intersection, they are

View File

@ -140,6 +140,7 @@ struct aproc {
unsigned abspos; /* frames produced */ unsigned abspos; /* frames produced */
struct aproc *ctl; /* MIDI control/sync */ struct aproc *ctl; /* MIDI control/sync */
struct aproc *mon; /* snoop output */ struct aproc *mon; /* snoop output */
unsigned autovol; /* adjust volume dynamically */
} mix; } mix;
struct { struct {
unsigned idle; /* frames since idleing */ unsigned idle; /* frames since idleing */
@ -239,7 +240,7 @@ void aproc_opos(struct aproc *, struct abuf *, int);
struct aproc *rfile_new(struct file *); struct aproc *rfile_new(struct file *);
struct aproc *wfile_new(struct file *); struct aproc *wfile_new(struct file *);
struct aproc *mix_new(char *, int, unsigned); struct aproc *mix_new(char *, int, unsigned, unsigned);
struct aproc *sub_new(char *, int, unsigned); struct aproc *sub_new(char *, int, unsigned);
struct aproc *resamp_new(char *, unsigned, unsigned); struct aproc *resamp_new(char *, unsigned, unsigned);
struct aproc *enc_new(char *, struct aparams *); struct aproc *enc_new(char *, struct aparams *);

View File

@ -42,6 +42,7 @@
.Op Fl t Ar mode .Op Fl t Ar mode
.Op Fl U Ar unit .Op Fl U Ar unit
.Op Fl v Ar volume .Op Fl v Ar volume
.Op Fl w Ar flag
.Op Fl x Ar policy .Op Fl x Ar policy
.Op Fl z Ar nframes .Op Fl z Ar nframes
.Ek .Ek
@ -114,7 +115,7 @@ Preceding streams
control MIDI ports control MIDI ports
.Pq Fl q , .Pq Fl q ,
and per-device options and per-device options
.Pq Fl abz .Pq Fl abwz
apply to this device. apply to this device.
Device mode and parameters are determined from streams Device mode and parameters are determined from streams
attached to it. attached to it.
@ -255,6 +256,22 @@ of clients as long as their number is small enough.
A good compromise is to use \-4dB attenuation (12 volume units) A good compromise is to use \-4dB attenuation (12 volume units)
for each additional client expected for each additional client expected
(115 if 2 clients are expected, 103 for 3 clients, and so on). (115 if 2 clients are expected, 103 for 3 clients, and so on).
.It Fl w Ar flag
Control whether the master volume resulting of all playback
streams of the device is automatically adjusted.
If the flag is
.Va on ,
then the master volume is lowered when necessary to ensure
clipping never occurs.
It should be set to
.Va off
to avoid lowering the volume twice if streams are already pre-scaled.
Note that stream volumes can be manually set
.Pq Fl v
and if they are set correctly, the master volume doesn't need
to be adjusted to avoid clipping.
The default is
.Va on .
.It Fl x Ar policy .It Fl x Ar policy
Action when the output stream cannot accept Action when the output stream cannot accept
recorded data fast enough or the input stream recorded data fast enough or the input stream
@ -298,7 +315,7 @@ to a 400 frame block size.
.Pp .Pp
On the command line, On the command line,
per-device parameters per-device parameters
.Pq Fl abz .Pq Fl abwz
must precede the device definition must precede the device definition
.Pq Fl f , .Pq Fl f ,
and per-stream parameters and per-stream parameters

View File

@ -251,6 +251,7 @@ struct cfdev {
struct aparams ipar; /* input (read) parameters */ struct aparams ipar; /* input (read) parameters */
struct aparams opar; /* output (write) parameters */ struct aparams opar; /* output (write) parameters */
unsigned hold; /* open immediately */ unsigned hold; /* open immediately */
unsigned autovol; /* adjust volumes */
unsigned bufsz; /* par.bufsz for sio device */ unsigned bufsz; /* par.bufsz for sio device */
unsigned round; /* par.round for sio device */ unsigned round; /* par.round for sio device */
unsigned mode; /* bitmap of MODE_XXX */ unsigned mode; /* bitmap of MODE_XXX */
@ -443,7 +444,7 @@ aucat_usage(void)
"[-o file]\n\t" "[-o file]\n\t"
"[-q device] [-r rate] [-s name] [-t mode] [-U unit] " "[-q device] [-r rate] [-s name] [-t mode] [-U unit] "
"[-v volume]\n\t" "[-v volume]\n\t"
"[-x policy] [-z nframes]\n", "[-w flag] [-x policy] [-z nframes]\n",
stderr); stderr);
} }
@ -512,8 +513,9 @@ aucat_main(int argc, char **argv)
cd->bufsz = 0; cd->bufsz = 0;
cd->round = 0; cd->round = 0;
cd->hold = 1; cd->hold = 1;
cd->autovol = 1;
while ((c = getopt(argc, argv, "a:dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:L:t:j:z:")) != -1) { while ((c = getopt(argc, argv, "a:w:dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:L:t:j:z:")) != -1) {
switch (c) { switch (c) {
case 'd': case 'd':
#ifdef DEBUG #ifdef DEBUG
@ -593,6 +595,9 @@ aucat_main(int argc, char **argv)
case 'a': case 'a':
cd->hold = opt_onoff(); cd->hold = opt_onoff();
break; break;
case 'w':
cd->autovol = opt_onoff();
break;
case 'q': case 'q':
cfmid_add(&cd->mids, optarg); cfmid_add(&cd->mids, optarg);
break; break;
@ -731,7 +736,7 @@ aucat_main(int argc, char **argv)
} else { } else {
d = dev_new_sio(cd->path, cd->mode | MODE_MIDIMASK, d = dev_new_sio(cd->path, cd->mode | MODE_MIDIMASK,
&cd->ipar, &cd->opar, cd->bufsz, cd->round, &cd->ipar, &cd->opar, cd->bufsz, cd->round,
cd->hold); cd->hold, cd->autovol);
} }
if (d == NULL) if (d == NULL)
errx(1, "%s: can't open device", cd->path); errx(1, "%s: can't open device", cd->path);

View File

@ -114,7 +114,7 @@ struct dev *dev_list = NULL;
struct dev * struct dev *
dev_new_sio(char *path, dev_new_sio(char *path,
unsigned mode, struct aparams *dipar, struct aparams *dopar, unsigned mode, struct aparams *dipar, struct aparams *dopar,
unsigned bufsz, unsigned round, unsigned hold) unsigned bufsz, unsigned round, unsigned hold, unsigned autovol)
{ {
struct dev *d; struct dev *d;
@ -132,6 +132,7 @@ dev_new_sio(char *path,
d->reqbufsz = bufsz; d->reqbufsz = bufsz;
d->reqround = round; d->reqround = round;
d->hold = hold; d->hold = hold;
d->autovol = autovol;
d->pstate = DEV_CLOSED; d->pstate = DEV_CLOSED;
d->next = dev_list; d->next = dev_list;
dev_list = d; dev_list = d;
@ -299,7 +300,7 @@ dev_open(struct dev *d)
* Create mixer, demuxer and monitor * Create mixer, demuxer and monitor
*/ */
if (d->mode & MODE_PLAY) { if (d->mode & MODE_PLAY) {
d->mix = mix_new("play", d->bufsz, d->round); d->mix = mix_new("play", d->bufsz, d->round, d->autovol);
d->mix->refs++; d->mix->refs++;
d->mix->u.mix.ctl = d->midi; d->mix->u.mix.ctl = d->midi;
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dev.h,v 1.27 2010/07/06 01:12:45 ratchov Exp $ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
* *
@ -34,6 +34,7 @@ struct dev {
unsigned reqround; /* block size */ unsigned reqround; /* block size */
unsigned reqrate; /* sample rate */ unsigned reqrate; /* sample rate */
unsigned hold; /* hold the device open ? */ unsigned hold; /* hold the device open ? */
unsigned autovol; /* auto adjust playvol ? */
unsigned refcnt; /* number of openers */ unsigned refcnt; /* number of openers */
#define DEV_CLOSED 0 /* closed */ #define DEV_CLOSED 0 /* closed */
#define DEV_INIT 1 /* stopped */ #define DEV_INIT 1 /* stopped */
@ -64,7 +65,8 @@ void dev_drain(struct dev *);
struct dev *dev_new_thru(void); struct dev *dev_new_thru(void);
struct dev *dev_new_loop(struct aparams *, struct aparams *, unsigned); struct dev *dev_new_loop(struct aparams *, struct aparams *, unsigned);
struct dev *dev_new_sio(char *, unsigned, struct dev *dev_new_sio(char *, unsigned,
struct aparams *, struct aparams *, unsigned, unsigned, unsigned); struct aparams *, struct aparams *,
unsigned, unsigned, unsigned, unsigned);
int dev_thruadd(struct dev *, char *, int, int); int dev_thruadd(struct dev *, char *, int, int);
void dev_midiattach(struct dev *, struct abuf *, struct abuf *); void dev_midiattach(struct dev *, struct abuf *, struct abuf *);
unsigned dev_roundof(struct dev *, unsigned); unsigned dev_roundof(struct dev *, unsigned);