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

View File

@ -140,6 +140,7 @@ struct aproc {
unsigned abspos; /* frames produced */
struct aproc *ctl; /* MIDI control/sync */
struct aproc *mon; /* snoop output */
unsigned autovol; /* adjust volume dynamically */
} mix;
struct {
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 *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 *resamp_new(char *, unsigned, unsigned);
struct aproc *enc_new(char *, struct aparams *);

View File

@ -42,6 +42,7 @@
.Op Fl t Ar mode
.Op Fl U Ar unit
.Op Fl v Ar volume
.Op Fl w Ar flag
.Op Fl x Ar policy
.Op Fl z Ar nframes
.Ek
@ -114,7 +115,7 @@ Preceding streams
control MIDI ports
.Pq Fl q ,
and per-device options
.Pq Fl abz
.Pq Fl abwz
apply to this device.
Device mode and parameters are determined from streams
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)
for each additional client expected
(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
Action when the output stream cannot accept
recorded data fast enough or the input stream
@ -298,7 +315,7 @@ to a 400 frame block size.
.Pp
On the command line,
per-device parameters
.Pq Fl abz
.Pq Fl abwz
must precede the device definition
.Pq Fl f ,
and per-stream parameters

View File

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

View File

@ -114,7 +114,7 @@ struct dev *dev_list = NULL;
struct dev *
dev_new_sio(char *path,
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;
@ -132,6 +132,7 @@ dev_new_sio(char *path,
d->reqbufsz = bufsz;
d->reqround = round;
d->hold = hold;
d->autovol = autovol;
d->pstate = DEV_CLOSED;
d->next = dev_list;
dev_list = d;
@ -299,7 +300,7 @@ dev_open(struct dev *d)
* Create mixer, demuxer and monitor
*/
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->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>
*
@ -34,6 +34,7 @@ struct dev {
unsigned reqround; /* block size */
unsigned reqrate; /* sample rate */
unsigned hold; /* hold the device open ? */
unsigned autovol; /* auto adjust playvol ? */
unsigned refcnt; /* number of openers */
#define DEV_CLOSED 0 /* closed */
#define DEV_INIT 1 /* stopped */
@ -64,7 +65,8 @@ void dev_drain(struct dev *);
struct dev *dev_new_thru(void);
struct dev *dev_new_loop(struct aparams *, struct aparams *, 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);
void dev_midiattach(struct dev *, struct abuf *, struct abuf *);
unsigned dev_roundof(struct dev *, unsigned);