mirror of https://github.com/ericonr/sndio.git
Add resamp_getcnt() routine to calculate the exact number of samples
that would be consumed and produced by the sampler rate converter. Use it to avoid partial samples that are not properly handled. Fixes last samples of certain files causing aucat to abort.
This commit is contained in:
parent
2562fa7eb4
commit
00ffc8f5ab
|
@ -439,16 +439,18 @@ slot_del(struct slot *s)
|
|||
xfree(s);
|
||||
}
|
||||
|
||||
static int
|
||||
slot_ocnt(struct slot *s, int icnt)
|
||||
static void
|
||||
slot_getcnt(struct slot *s, int *icnt, int *ocnt)
|
||||
{
|
||||
return s->resampbuf ? resamp_ocnt(&s->resamp, icnt) : icnt;
|
||||
}
|
||||
int cnt;
|
||||
|
||||
static int
|
||||
slot_icnt(struct slot *s, int ocnt)
|
||||
{
|
||||
return s->resampbuf ? resamp_icnt(&s->resamp, ocnt) : ocnt;
|
||||
if (s->resampbuf)
|
||||
resamp_getcnt(&s->resamp, icnt, ocnt);
|
||||
else {
|
||||
cnt = (*icnt < *ocnt) ? *icnt : *ocnt;
|
||||
*icnt = cnt;
|
||||
*ocnt = cnt;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -529,13 +531,9 @@ slot_mix_badd(struct slot *s, adata_t *odata)
|
|||
}
|
||||
while (otodo > 0) {
|
||||
idata = (adata_t *)abuf_rgetblk(&s->buf, &len);
|
||||
|
||||
icnt = len / s->bpf;
|
||||
ocnt = slot_ocnt(s, icnt);
|
||||
if (ocnt > otodo) {
|
||||
ocnt = otodo;
|
||||
icnt = slot_icnt(s, ocnt);
|
||||
}
|
||||
slot_getcnt(s, &icnt, &ocnt);
|
||||
if (icnt == 0)
|
||||
break;
|
||||
play_filt_dec(s, idata, odata, icnt, ocnt);
|
||||
|
@ -607,13 +605,9 @@ slot_sub_bcopy(struct slot *s, adata_t *idata, int itodo)
|
|||
|
||||
while (itodo > 0) {
|
||||
odata = (adata_t *)abuf_wgetblk(&s->buf, &len);
|
||||
|
||||
ocnt = len / s->bpf;
|
||||
icnt = slot_icnt(s, ocnt);
|
||||
if (icnt > itodo) {
|
||||
icnt = itodo;
|
||||
ocnt = slot_ocnt(s, icnt);
|
||||
}
|
||||
slot_getcnt(s, &icnt, &ocnt);
|
||||
if (ocnt == 0)
|
||||
break;
|
||||
rec_filt_enc(s, idata, odata, icnt, ocnt);
|
||||
|
|
55
aucat/dsp.c
55
aucat/dsp.c
|
@ -268,35 +268,50 @@ aparams_native(struct aparams *par)
|
|||
}
|
||||
|
||||
/*
|
||||
* return the number of output frames resamp_do() would produce with
|
||||
* the given number of input frames
|
||||
* return the number of input and output frame that would
|
||||
* be consumed
|
||||
*/
|
||||
int
|
||||
resamp_ocnt(struct resamp *p, int icnt)
|
||||
void
|
||||
resamp_getcnt(struct resamp *p, int *icnt, int *ocnt)
|
||||
{
|
||||
return ((long long)p->oblksz * icnt + p->diff) / p->iblksz;
|
||||
}
|
||||
int diff, ifr, ofr;
|
||||
|
||||
/*
|
||||
* return the number of input frames resamp_do() needs in order to
|
||||
* produce the given number of output frames
|
||||
*/
|
||||
int
|
||||
resamp_icnt(struct resamp *p, int ocnt)
|
||||
{
|
||||
return ((long long)p->iblksz * ocnt - p->diff +
|
||||
p->oblksz - 1) / p->oblksz;
|
||||
diff = p->diff;
|
||||
ifr = *icnt;
|
||||
ofr = *ocnt;
|
||||
|
||||
for (;;) {
|
||||
if (diff < 0) {
|
||||
if (ifr == 0)
|
||||
break;
|
||||
diff += p->oblksz;
|
||||
ifr--;
|
||||
} else if (diff > 0) {
|
||||
if (ofr == 0)
|
||||
break;
|
||||
diff -= p->iblksz;
|
||||
ofr--;
|
||||
} else {
|
||||
if (ifr == 0 || ofr == 0)
|
||||
break;
|
||||
diff -= p->iblksz;
|
||||
diff += p->oblksz;
|
||||
ifr--;
|
||||
ofr--;
|
||||
}
|
||||
}
|
||||
*icnt -= ifr;
|
||||
*ocnt -= ofr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resample the given number of frames. The number of output frames
|
||||
* must match the coresponding number the input frames. Either
|
||||
* use:
|
||||
* must match the coresponding number the input frames. Either always
|
||||
* use icnt and ocnt such that:
|
||||
*
|
||||
* icnt * orate = ocnt * irate
|
||||
* icnt * oblksz = ocnt * iblksz
|
||||
*
|
||||
* or use resamp_icnt() or resamp_ocnt() to calculate the proper
|
||||
* numbers.
|
||||
* or use resamp_getcnt() to calculate the proper numbers.
|
||||
*/
|
||||
void
|
||||
resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt)
|
||||
|
|
|
@ -147,8 +147,7 @@ int aparams_strtoenc(struct aparams *, char *);
|
|||
int aparams_enctostr(struct aparams *, char *);
|
||||
int aparams_native(struct aparams *);
|
||||
|
||||
int resamp_ocnt(struct resamp *, int);
|
||||
int resamp_icnt(struct resamp *, int);
|
||||
void resamp_getcnt(struct resamp *, int *, int *);
|
||||
void resamp_do(struct resamp *, adata_t *, adata_t *, int, int);
|
||||
void resamp_init(struct resamp *, unsigned int, unsigned int, int);
|
||||
void enc_do(struct conv *, unsigned char *, unsigned char *, int);
|
||||
|
|
Loading…
Reference in New Issue