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_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_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_onmove(struct dev *, int);
|
||||
|
@ -560,56 +556,14 @@ slot_skip(struct slot *s)
|
|||
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
|
||||
* there are frames to drop, less frames are consumed from the input
|
||||
* Mix the slot input block over the output block
|
||||
*/
|
||||
void
|
||||
dev_mix_badd(struct dev *d, struct slot *s)
|
||||
{
|
||||
adata_t *idata, *odata;
|
||||
int icount;
|
||||
adata_t *idata, *odata, *in;
|
||||
int icount, i, offs, vol, nch;
|
||||
|
||||
odata = DEV_PBUF(d);
|
||||
idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
|
||||
|
@ -622,7 +576,43 @@ dev_mix_badd(struct dev *d, struct slot *s)
|
|||
panic();
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
void
|
||||
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 i, vol, offs, nch;
|
||||
|
||||
|
||||
if (s->mode & MODE_MON) {
|
||||
moffs = d->poffs + d->round;
|
||||
if (moffs == d->psize)
|
||||
|
@ -735,8 +688,44 @@ dev_sub_bcopy(struct dev *d, struct slot *s)
|
|||
panic();
|
||||
}
|
||||
#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
|
||||
*/
|
||||
int
|
||||
void
|
||||
resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)
|
||||
{
|
||||
unsigned int nch;
|
||||
adata_t *idata;
|
||||
unsigned int oblksz;
|
||||
unsigned int ifr;
|
||||
int s, ds, diff;
|
||||
adata_t *odata;
|
||||
unsigned int iblksz;
|
||||
unsigned int ofr;
|
||||
unsigned int c;
|
||||
adata_t *ctxbuf, *ctx;
|
||||
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
|
||||
* 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;
|
||||
odata = out;
|
||||
diff = p->diff;
|
||||
diff = p->oblksz;
|
||||
iblksz = p->iblksz;
|
||||
oblksz = p->oblksz;
|
||||
ctxbuf = p->ctx;
|
||||
ctx_start = p->ctx_start;
|
||||
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 (;;) {
|
||||
if (diff < 0) {
|
||||
if (ifr == 0)
|
||||
if (diff >= oblksz) {
|
||||
if (todo == 0)
|
||||
break;
|
||||
ctx_start ^= 1;
|
||||
ctx = ctxbuf + ctx_start;
|
||||
|
@ -253,43 +244,21 @@ resamp_do(struct resamp *p, adata_t *in, adata_t *out, int todo)
|
|||
*ctx = *idata++;
|
||||
ctx += RESAMP_NCTX;
|
||||
}
|
||||
diff += oblksz;
|
||||
ifr--;
|
||||
} else if (diff > 0) {
|
||||
if (ofr == 0)
|
||||
break;
|
||||
diff -= oblksz;
|
||||
todo--;
|
||||
} else {
|
||||
ctx = ctxbuf;
|
||||
for (c = nch; c > 0; c--) {
|
||||
s = ctx[ctx_start];
|
||||
ds = ctx[ctx_start ^ 1] - s;
|
||||
s = ctx[ctx_start ^ 1];
|
||||
ds = ctx[ctx_start] - s;
|
||||
ctx += RESAMP_NCTX;
|
||||
*odata++ = s + ADATA_MULDIV(ds, diff, oblksz);
|
||||
}
|
||||
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--;
|
||||
diff += iblksz;
|
||||
}
|
||||
}
|
||||
p->diff = diff;
|
||||
|
||||
p->ctx_start = ctx_start;
|
||||
return oblksz - ofr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -303,7 +272,6 @@ resamp_init(struct resamp *p, unsigned int iblksz,
|
|||
|
||||
p->iblksz = iblksz;
|
||||
p->oblksz = oblksz;
|
||||
p->diff = 0;
|
||||
p->nch = nch;
|
||||
p->ctx_start = 0;
|
||||
for (i = 0; i < NCHAN_MAX * RESAMP_NCTX; i++)
|
||||
|
|
|
@ -115,7 +115,6 @@ struct resamp {
|
|||
unsigned int ctx_start;
|
||||
adata_t ctx[NCHAN_MAX * RESAMP_NCTX];
|
||||
unsigned int iblksz, oblksz;
|
||||
int diff;
|
||||
int nch;
|
||||
};
|
||||
|
||||
|
@ -146,7 +145,7 @@ int aparams_strtoenc(struct aparams *, char *);
|
|||
int aparams_enctostr(struct aparams *, char *);
|
||||
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 enc_do(struct conv *, unsigned char *, unsigned char *, int);
|
||||
void enc_sil_do(struct conv *, unsigned char *, int);
|
||||
|
|
Loading…
Reference in New Issue