sndiod: If mode not allowed in opt structure just play/record silence

This is similar to what we do when device is open and its mode doesn't
match requested mode.
This commit is contained in:
Alexandre Ratchov 2021-04-26 09:50:14 +02:00
parent e450bab99e
commit 12b31d021a
1 changed files with 33 additions and 24 deletions

View File

@ -498,6 +498,14 @@ dev_mix_badd(struct dev *d, struct slot *s)
panic();
}
#endif
if (!(s->opt->mode & MODE_PLAY)) {
/*
* playback not allowed in opt structure, produce silence
*/
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
return;
}
/*
* Apply the following processing chain:
@ -599,13 +607,6 @@ dev_sub_bcopy(struct dev *d, struct slot *s)
int i, vol, offs, nch;
if (s->mode & MODE_MON) {
moffs = d->poffs + d->round;
if (moffs == d->psize)
moffs = 0;
idata = d->pbuf + moffs * d->pchan;
} else
idata = d->rbuf;
odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount);
#ifdef DEBUG
if (ocount < s->round * s->sub.bpf) {
@ -613,6 +614,21 @@ dev_sub_bcopy(struct dev *d, struct slot *s)
panic();
}
#endif
if (s->opt->mode & MODE_MON) {
moffs = d->poffs + d->round;
if (moffs == d->psize)
moffs = 0;
idata = d->pbuf + moffs * d->pchan;
} else if (s->opt->mode & MODE_REC) {
idata = d->rbuf;
} else {
/*
* recording not allowed in opt structure, produce silence
*/
enc_sil_do(&s->sub.enc, odata, s->round);
abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
return;
}
/*
* Apply the following processing chain:
@ -1772,25 +1788,8 @@ slot_new(struct opt *opt, unsigned int id, char *who,
NULL, -1, 127, s->vol);
found:
if ((mode & MODE_REC) && (opt->mode & MODE_MON)) {
mode |= MODE_MON;
mode &= ~MODE_REC;
}
if ((mode & opt->mode) != mode) {
if (log_level >= 1) {
slot_log(s);
log_puts(": requested mode not allowed\n");
}
return NULL;
}
if (!dev_ref(opt->dev))
return NULL;
if ((mode & opt->dev->mode) != mode) {
if (log_level >= 1) {
slot_log(s);
log_puts(": requested mode not supported\n");
}
}
s->opt = opt;
s->ops = ops;
s->arg = arg;
@ -1871,6 +1870,16 @@ slot_attach(struct slot *s)
struct dev *d = s->opt->dev;
long long pos;
if (((s->mode & MODE_PLAY) && !(s->opt->mode & MODE_PLAY)) ||
((s->mode & MODE_RECMASK) && !(s->opt->mode & MODE_RECMASK))) {
if (log_level >= 1) {
slot_log(s);
log_puts(" at ");
log_puts(s->opt->name);
log_puts(": mode not allowed on this sub-device\n");
}
}
/*
* setup converions layer
*/