Merge branch 'master' into mixer

This commit is contained in:
Alexandre Ratchov 2018-06-08 08:24:06 +02:00
commit 562ee176e9
3 changed files with 102 additions and 146 deletions

View File

@ -46,12 +46,8 @@ void dev_midi_omsg(void *, unsigned char *, int);
void dev_midi_fill(void *, int); void dev_midi_fill(void *, int);
void dev_midi_exit(void *); void dev_midi_exit(void *);
int play_filt_resamp(struct slot *, void *, void *, int);
int play_filt_dec(struct slot *, void *, void *, int);
void dev_mix_badd(struct dev *, struct slot *); void dev_mix_badd(struct dev *, struct slot *);
void dev_mix_adjvol(struct dev *); void dev_mix_adjvol(struct dev *);
int rec_filt_resamp(struct slot *, void *, void *, int);
int rec_filt_enc(struct slot *, void *, void *, int);
void dev_sub_bcopy(struct dev *, struct slot *); void dev_sub_bcopy(struct dev *, struct slot *);
void dev_onmove(struct dev *, int); void dev_onmove(struct dev *, int);
@ -560,56 +556,14 @@ slot_skip(struct slot *s)
return max - s->skip; return max - s->skip;
} }
int
play_filt_resamp(struct slot *s, void *res_in, void *out, int todo)
{
int i, offs, vol, nch;
void *in;
if (s->mix.resampbuf) {
todo = resamp_do(&s->mix.resamp,
res_in, s->mix.resampbuf, todo);
in = s->mix.resampbuf;
} else
in = res_in;
nch = s->mix.cmap.nch;
vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join;
cmap_add(&s->mix.cmap, in, out, vol, todo);
offs = 0;
for (i = s->mix.join - 1; i > 0; i--) {
offs += nch;
cmap_add(&s->mix.cmap, (adata_t *)in + offs, out, vol, todo);
}
offs = 0;
for (i = s->mix.expand - 1; i > 0; i--) {
offs += nch;
cmap_add(&s->mix.cmap, in, (adata_t *)out + offs, vol, todo);
}
return todo;
}
int
play_filt_dec(struct slot *s, void *in, void *out, int todo)
{
void *tmp;
tmp = s->mix.decbuf;
if (tmp)
dec_do(&s->mix.dec, in, tmp, todo);
return play_filt_resamp(s, tmp ? tmp : in, out, todo);
}
/* /*
* mix "todo" frames from the input block over the output block; if * Mix the slot input block over the output block
* there are frames to drop, less frames are consumed from the input
*/ */
void void
dev_mix_badd(struct dev *d, struct slot *s) dev_mix_badd(struct dev *d, struct slot *s)
{ {
adata_t *idata, *odata; adata_t *idata, *odata, *in;
int icount; int icount, i, offs, vol, nch;
odata = DEV_PBUF(d); odata = DEV_PBUF(d);
idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount); idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
@ -622,7 +576,43 @@ dev_mix_badd(struct dev *d, struct slot *s)
panic(); panic();
} }
#endif #endif
play_filt_dec(s, idata, odata, s->round);
/*
* Apply the following processing chain:
*
* dec -> resamp-> cmap
*
* where the first two are optional.
*/
in = idata;
if (s->mix.decbuf) {
dec_do(&s->mix.dec, (void *)in, s->mix.decbuf, s->round);
in = s->mix.decbuf;
}
if (s->mix.resampbuf) {
resamp_do(&s->mix.resamp, in, s->mix.resampbuf, s->round);
in = s->mix.resampbuf;
}
nch = s->mix.cmap.nch;
vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join;
cmap_add(&s->mix.cmap, in, odata, vol, d->round);
offs = 0;
for (i = s->mix.join - 1; i > 0; i--) {
offs += nch;
cmap_add(&s->mix.cmap, in + offs, odata, vol, d->round);
}
offs = 0;
for (i = s->mix.expand - 1; i > 0; i--) {
offs += nch;
cmap_add(&s->mix.cmap, in, odata + offs, vol, d->round);
}
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf); abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
} }
@ -671,56 +661,19 @@ dev_mix_adjvol(struct dev *d)
} }
} }
int
rec_filt_resamp(struct slot *s, void *in, void *res_out, int todo)
{
int i, vol, offs, nch;
void *out = res_out;
out = (s->sub.resampbuf) ? s->sub.resampbuf : res_out;
nch = s->sub.cmap.nch;
vol = ADATA_UNIT / s->sub.join;
cmap_copy(&s->sub.cmap, in, out, vol, todo);
offs = 0;
for (i = s->sub.join - 1; i > 0; i--) {
offs += nch;
cmap_add(&s->sub.cmap, (adata_t *)in + offs, out, vol, todo);
}
offs = 0;
for (i = s->sub.expand - 1; i > 0; i--) {
offs += nch;
cmap_copy(&s->sub.cmap, in, (adata_t *)out + offs, vol, todo);
}
if (s->sub.resampbuf) {
todo = resamp_do(&s->sub.resamp,
s->sub.resampbuf, res_out, todo);
}
return todo;
}
int
rec_filt_enc(struct slot *s, void *in, void *out, int todo)
{
void *tmp;
tmp = s->sub.encbuf;
todo = rec_filt_resamp(s, in, tmp ? tmp : out, todo);
if (tmp)
enc_do(&s->sub.enc, tmp, out, todo);
return todo;
}
/* /*
* Copy data from slot to device * Copy data from slot to device
*/ */
void void
dev_sub_bcopy(struct dev *d, struct slot *s) dev_sub_bcopy(struct dev *d, struct slot *s)
{ {
adata_t *idata, *odata; adata_t *idata, *enc_out, *resamp_out, *cmap_out;
void *odata;
int ocount, moffs; int ocount, moffs;
int i, vol, offs, nch;
if (s->mode & MODE_MON) { if (s->mode & MODE_MON) {
moffs = d->poffs + d->round; moffs = d->poffs + d->round;
if (moffs == d->psize) if (moffs == d->psize)
@ -735,8 +688,44 @@ dev_sub_bcopy(struct dev *d, struct slot *s)
panic(); panic();
} }
#endif #endif
ocount = rec_filt_enc(s, idata, odata, d->round);
abuf_wcommit(&s->sub.buf, ocount * s->sub.bpf); /*
* Apply the following processing chain:
*
* cmap -> resamp -> enc
*
* where the last two are optional.
*/
enc_out = odata;
resamp_out = s->sub.encbuf ? s->sub.encbuf : enc_out;
cmap_out = s->sub.resampbuf ? s->sub.resampbuf : resamp_out;
nch = s->sub.cmap.nch;
vol = ADATA_UNIT / s->sub.join;
cmap_copy(&s->sub.cmap, idata, cmap_out, vol, d->round);
offs = 0;
for (i = s->sub.join - 1; i > 0; i--) {
offs += nch;
cmap_add(&s->sub.cmap, idata + offs, cmap_out, vol, d->round);
}
offs = 0;
for (i = s->sub.expand - 1; i > 0; i--) {
offs += nch;
cmap_copy(&s->sub.cmap, idata, cmap_out + offs, vol, d->round);
}
if (s->sub.resampbuf) {
resamp_do(&s->sub.resamp,
s->sub.resampbuf, resamp_out, d->round);
}
if (s->sub.encbuf)
enc_do(&s->sub.enc, s->sub.encbuf, (void *)enc_out, s->round);
abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
} }
/* /*

View File

@ -200,21 +200,26 @@ aparams_native(struct aparams *par)
/* /*
* resample the given number of frames * resample the given number of frames
*/ */
int void
resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo) resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)
{ {
unsigned int nch; unsigned int nch;
adata_t *idata; adata_t *idata;
unsigned int oblksz; unsigned int oblksz;
unsigned int ifr;
int s, ds, diff; int s, ds, diff;
adata_t *odata; adata_t *odata;
unsigned int iblksz; unsigned int iblksz;
unsigned int ofr;
unsigned int c; unsigned int c;
adata_t *ctxbuf, *ctx; adata_t *ctxbuf, *ctx;
unsigned int ctx_start; unsigned int ctx_start;
#ifdef DEBUG
if (todo % p->iblksz != 0) {
log_puts("resamp_do: partial blocks not supported\n");
panic();
}
#endif
/* /*
* Partially copy structures into local variables, to avoid * Partially copy structures into local variables, to avoid
* unnecessary indirections; this also allows the compiler to * unnecessary indirections; this also allows the compiler to
@ -222,30 +227,16 @@ resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)
*/ */
idata = in; idata = in;
odata = out; odata = out;
diff = p->diff; diff = p->oblksz;
iblksz = p->iblksz; iblksz = p->iblksz;
oblksz = p->oblksz; oblksz = p->oblksz;
ctxbuf = p->ctx; ctxbuf = p->ctx;
ctx_start = p->ctx_start; ctx_start = p->ctx_start;
nch = p->nch; nch = p->nch;
ifr = todo;
ofr = oblksz;
/*
* Start conversion.
*/
#ifdef DEBUG
if (log_level >= 4) {
log_puts("resamp: copying ");
log_puti(todo);
log_puts(" frames, diff = ");
log_putu(diff);
log_puts("\n");
}
#endif
for (;;) { for (;;) {
if (diff < 0) { if (diff >= oblksz) {
if (ifr == 0) if (todo == 0)
break; break;
ctx_start ^= 1; ctx_start ^= 1;
ctx = ctxbuf + ctx_start; ctx = ctxbuf + ctx_start;
@ -253,43 +244,21 @@ resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)
*ctx = *idata++; *ctx = *idata++;
ctx += RESAMP_NCTX; ctx += RESAMP_NCTX;
} }
diff += oblksz; diff -= oblksz;
ifr--; todo--;
} else if (diff > 0) { } else {
if (ofr == 0)
break;
ctx = ctxbuf; ctx = ctxbuf;
for (c = nch; c > 0; c--) { for (c = nch; c > 0; c--) {
s = ctx[ctx_start]; s = ctx[ctx_start ^ 1];
ds = ctx[ctx_start ^ 1] - s; ds = ctx[ctx_start] - s;
ctx += RESAMP_NCTX; ctx += RESAMP_NCTX;
*odata++ = s + ADATA_MULDIV(ds, diff, oblksz); *odata++ = s + ADATA_MULDIV(ds, diff, oblksz);
} }
diff -= iblksz; diff += iblksz;
ofr--;
} else {
if (ifr == 0 || ofr == 0)
break;
ctx = ctxbuf + ctx_start;
for (c = nch; c > 0; c--) {
*odata++ = *ctx;
ctx += RESAMP_NCTX;
}
ctx_start ^= 1;
ctx = ctxbuf + ctx_start;
for (c = nch; c > 0; c--) {
*ctx = *idata++;
ctx += RESAMP_NCTX;
}
diff -= iblksz;
diff += oblksz;
ifr--;
ofr--;
} }
} }
p->diff = diff;
p->ctx_start = ctx_start; p->ctx_start = ctx_start;
return oblksz - ofr;
} }
/* /*
@ -303,7 +272,6 @@ resamp_init(struct resamp *p, unsigned int iblksz,
p->iblksz = iblksz; p->iblksz = iblksz;
p->oblksz = oblksz; p->oblksz = oblksz;
p->diff = 0;
p->nch = nch; p->nch = nch;
p->ctx_start = 0; p->ctx_start = 0;
for (i = 0; i < NCHAN_MAX * RESAMP_NCTX; i++) for (i = 0; i < NCHAN_MAX * RESAMP_NCTX; i++)

View File

@ -115,7 +115,6 @@ struct resamp {
unsigned int ctx_start; unsigned int ctx_start;
adata_t ctx[NCHAN_MAX * RESAMP_NCTX]; adata_t ctx[NCHAN_MAX * RESAMP_NCTX];
unsigned int iblksz, oblksz; unsigned int iblksz, oblksz;
int diff;
int nch; int nch;
}; };
@ -146,7 +145,7 @@ int aparams_strtoenc(struct aparams *, char *);
int aparams_enctostr(struct aparams *, char *); int aparams_enctostr(struct aparams *, char *);
int aparams_native(struct aparams *); int aparams_native(struct aparams *);
int resamp_do(struct resamp *, adata_t *, adata_t *, int); void resamp_do(struct resamp *, adata_t *, adata_t *, int);
void resamp_init(struct resamp *, unsigned int, unsigned int, int); void resamp_init(struct resamp *, unsigned int, unsigned int, int);
void enc_do(struct conv *, unsigned char *, unsigned char *, int); void enc_do(struct conv *, unsigned char *, unsigned char *, int);
void enc_sil_do(struct conv *, unsigned char *, int); void enc_sil_do(struct conv *, unsigned char *, int);