version 1.153, 2016/05/26 06:17:31 |
version 1.154, 2016/05/27 15:38:27 |
|
|
free(s); |
free(s); |
} |
} |
|
|
|
static int |
|
slot_ocnt(struct slot *s, int icnt) |
|
{ |
|
return s->resampbuf ? resamp_ocnt(&s->resamp, icnt) : icnt; |
|
} |
|
|
|
static int |
|
slot_icnt(struct slot *s, int ocnt) |
|
{ |
|
return s->resampbuf ? resamp_icnt(&s->resamp, ocnt) : ocnt; |
|
} |
|
|
static void |
static void |
play_filt_resamp(struct slot *s, void *res_in, void *out, int *icnt, int *ocnt) |
play_filt_resamp(struct slot *s, void *res_in, void *out, int icnt, int ocnt) |
{ |
{ |
int i, offs, vol, nch; |
int i, offs, vol, nch; |
void *in; |
void *in; |
|
|
|
|
nch = s->cmap.nch; |
nch = s->cmap.nch; |
vol = s->vol / s->join; /* XXX */ |
vol = s->vol / s->join; /* XXX */ |
cmap_add(&s->cmap, in, out, vol, *ocnt); |
cmap_add(&s->cmap, in, out, vol, ocnt); |
|
|
offs = 0; |
offs = 0; |
for (i = s->join - 1; i > 0; i--) { |
for (i = s->join - 1; i > 0; i--) { |
offs += nch; |
offs += nch; |
cmap_add(&s->cmap, (adata_t *)in + offs, out, vol, *ocnt); |
cmap_add(&s->cmap, (adata_t *)in + offs, out, vol, ocnt); |
} |
} |
offs = 0; |
offs = 0; |
for (i = s->expand - 1; i > 0; i--) { |
for (i = s->expand - 1; i > 0; i--) { |
offs += nch; |
offs += nch; |
cmap_add(&s->cmap, in, (adata_t *)out + offs, vol, *ocnt); |
cmap_add(&s->cmap, in, (adata_t *)out + offs, vol, ocnt); |
} |
} |
} |
} |
|
|
static void |
static void |
play_filt_dec(struct slot *s, void *in, void *out, int *icnt, int *ocnt) |
play_filt_dec(struct slot *s, void *in, void *out, int icnt, int ocnt) |
{ |
{ |
void *tmp; |
void *tmp; |
|
|
|
|
if (tmp) { |
if (tmp) { |
switch (s->afile.fmt) { |
switch (s->afile.fmt) { |
case AFILE_FMT_PCM: |
case AFILE_FMT_PCM: |
dec_do(&s->conv, in, tmp, *icnt); |
dec_do(&s->conv, in, tmp, icnt); |
break; |
break; |
case AFILE_FMT_ULAW: |
case AFILE_FMT_ULAW: |
dec_do_ulaw(&s->conv, in, tmp, *icnt, 0); |
dec_do_ulaw(&s->conv, in, tmp, icnt, 0); |
break; |
break; |
case AFILE_FMT_ALAW: |
case AFILE_FMT_ALAW: |
dec_do_ulaw(&s->conv, in, tmp, *icnt, 1); |
dec_do_ulaw(&s->conv, in, tmp, icnt, 1); |
break; |
break; |
case AFILE_FMT_FLOAT: |
case AFILE_FMT_FLOAT: |
dec_do_float(&s->conv, in, tmp, *icnt); |
dec_do_float(&s->conv, in, tmp, icnt); |
break; |
break; |
} |
} |
} else |
} else |
|
|
slot_mix_badd(struct slot *s, adata_t *odata) |
slot_mix_badd(struct slot *s, adata_t *odata) |
{ |
{ |
adata_t *idata; |
adata_t *idata; |
int len, icnt, ocnt; |
int len, icnt, ocnt, otodo, odone; |
|
|
idata = (adata_t *)abuf_rgetblk(&s->buf, &len); |
odone = 0; |
icnt = len / s->bpf; |
otodo = dev_round; |
if (icnt > s->round) |
while (otodo > 0) { |
icnt = s->round; |
idata = (adata_t *)abuf_rgetblk(&s->buf, &len); |
#ifdef DEBUG |
|
if (icnt == 0) { |
icnt = len / s->bpf; |
log_puts("slot_mix_badd: not enough data\n"); |
ocnt = slot_ocnt(s, icnt); |
panic(); |
if (ocnt > otodo) { |
|
ocnt = otodo; |
|
icnt = slot_icnt(s, ocnt); |
|
} |
|
if (icnt == 0) |
|
break; |
|
play_filt_dec(s, idata, odata, icnt, ocnt); |
|
abuf_rdiscard(&s->buf, icnt * s->bpf); |
|
otodo -= ocnt; |
|
odone += ocnt; |
|
odata += ocnt * dev_pchan; |
} |
} |
#endif |
return odone; |
ocnt = dev_round; |
|
play_filt_dec(s, idata, odata, &icnt, &ocnt); |
|
abuf_rdiscard(&s->buf, icnt * s->bpf); |
|
return ocnt; |
|
} |
} |
|
|
static void |
static void |
rec_filt_resamp(struct slot *s, void *in, void *res_out, int *icnt, int *ocnt) |
rec_filt_resamp(struct slot *s, void *in, void *res_out, int icnt, int ocnt) |
{ |
{ |
int i, vol, offs, nch; |
int i, vol, offs, nch; |
void *out = res_out; |
void *out = res_out; |
|
|
|
|
nch = s->cmap.nch; |
nch = s->cmap.nch; |
vol = ADATA_UNIT / s->join; |
vol = ADATA_UNIT / s->join; |
cmap_copy(&s->cmap, in, out, vol, *icnt); |
cmap_copy(&s->cmap, in, out, vol, icnt); |
|
|
offs = 0; |
offs = 0; |
for (i = s->join - 1; i > 0; i--) { |
for (i = s->join - 1; i > 0; i--) { |
offs += nch; |
offs += nch; |
cmap_add(&s->cmap, (adata_t *)in + offs, out, vol, *icnt); |
cmap_add(&s->cmap, (adata_t *)in + offs, out, vol, icnt); |
} |
} |
offs = 0; |
offs = 0; |
for (i = s->expand - 1; i > 0; i--) { |
for (i = s->expand - 1; i > 0; i--) { |
offs += nch; |
offs += nch; |
cmap_copy(&s->cmap, in, (adata_t *)out + offs, vol, *icnt); |
cmap_copy(&s->cmap, in, (adata_t *)out + offs, vol, icnt); |
} |
} |
if (s->resampbuf) |
if (s->resampbuf) |
resamp_do(&s->resamp, s->resampbuf, res_out, icnt, ocnt); |
resamp_do(&s->resamp, s->resampbuf, res_out, icnt, ocnt); |
else |
else |
*ocnt = *icnt; |
ocnt = icnt; |
} |
} |
|
|
static void |
static void |
rec_filt_enc(struct slot *s, void *in, void *out, int *icnt, int *ocnt) |
rec_filt_enc(struct slot *s, void *in, void *out, int icnt, int ocnt) |
{ |
{ |
void *tmp; |
void *tmp; |
|
|
tmp = s->convbuf; |
tmp = s->convbuf; |
rec_filt_resamp(s, in, tmp ? tmp : out, icnt, ocnt); |
rec_filt_resamp(s, in, tmp ? tmp : out, icnt, ocnt); |
if (tmp) |
if (tmp) |
enc_do(&s->conv, tmp, out, *ocnt); |
enc_do(&s->conv, tmp, out, ocnt); |
} |
} |
|
|
/* |
/* |
|
|
* but not more than a block. |
* but not more than a block. |
*/ |
*/ |
static void |
static void |
slot_sub_bcopy(struct slot *s, adata_t *idata, int todo) |
slot_sub_bcopy(struct slot *s, adata_t *idata, int itodo) |
{ |
{ |
adata_t *odata; |
adata_t *odata; |
int len, icnt, ocnt; |
int len, icnt, ocnt; |
|
|
odata = (adata_t *)abuf_wgetblk(&s->buf, &len); |
while (itodo > 0) { |
#ifdef DEBUG |
odata = (adata_t *)abuf_wgetblk(&s->buf, &len); |
if (len < s->round * s->bpf) { |
|
log_puts("slot_sub_bcopy: not enough space\n"); |
ocnt = len / s->bpf; |
panic(); |
icnt = slot_icnt(s, ocnt); |
|
if (icnt > itodo) { |
|
icnt = itodo; |
|
ocnt = slot_ocnt(s, icnt); |
|
} |
|
if (ocnt == 0) |
|
break; |
|
rec_filt_enc(s, idata, odata, icnt, ocnt); |
|
abuf_wcommit(&s->buf, ocnt * s->bpf); |
|
itodo -= icnt; |
|
idata += icnt * dev_rchan; |
} |
} |
#endif |
|
icnt = todo; |
|
ocnt = len / s->bpf; |
|
rec_filt_enc(s, idata, odata, &icnt, &ocnt); |
|
abuf_wcommit(&s->buf, ocnt * s->bpf); |
|
} |
} |
|
|
static int |
static int |