mirror of https://github.com/ericonr/sndio.git
Merge branch 'master' into mixer
This commit is contained in:
commit
562ee176e9
177
sndiod/dev.c
177
sndiod/dev.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
68
sndiod/dsp.c
68
sndiod/dsp.c
|
@ -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++)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue