diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2016-06-07 06:11:33 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2016-06-07 06:11:33 +0000 |
commit | 3a506d1eb7b6731c6f22862e19865bc0bdd6fd43 (patch) | |
tree | 3073fa3dd475f720c257c051b859a0863a4a66d0 | |
parent | 5a0bb33064ebc97a938c6637c52cd3362261d455 (diff) |
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.
-rw-r--r-- | usr.bin/aucat/aucat.c | 34 | ||||
-rw-r--r-- | usr.bin/aucat/dsp.c | 57 | ||||
-rw-r--r-- | usr.bin/aucat/dsp.h | 5 |
3 files changed, 52 insertions, 44 deletions
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c index 7891479e1e1..33aad5a2d4c 100644 --- a/usr.bin/aucat/aucat.c +++ b/usr.bin/aucat/aucat.c @@ -424,16 +424,18 @@ slot_del(struct slot *s) free(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 @@ -505,13 +507,9 @@ slot_mix_badd(struct slot *s, adata_t *odata) otodo = dev_round; 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); - } + ocnt = otodo; + slot_getcnt(s, &icnt, &ocnt); if (icnt == 0) break; play_filt_dec(s, idata, odata, icnt, ocnt); @@ -574,13 +572,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); - } + icnt = itodo; + slot_getcnt(s, &icnt, &ocnt); if (ocnt == 0) break; rec_filt_enc(s, idata, odata, icnt, ocnt); diff --git a/usr.bin/aucat/dsp.c b/usr.bin/aucat/dsp.c index 1a8b5eb2cdd..22526cc9b22 100644 --- a/usr.bin/aucat/dsp.c +++ b/usr.bin/aucat/dsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsp.c,v 1.6 2016/05/27 16:18:59 ratchov Exp $ */ +/* $OpenBSD: dsp.c,v 1.7 2016/06/07 06:11:32 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org> * @@ -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) diff --git a/usr.bin/aucat/dsp.h b/usr.bin/aucat/dsp.h index b71c77f0ebc..d56e2f034a6 100644 --- a/usr.bin/aucat/dsp.h +++ b/usr.bin/aucat/dsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dsp.h,v 1.3 2016/05/27 15:38:27 ratchov Exp $ */ +/* $OpenBSD: dsp.h,v 1.4 2016/06/07 06:11:32 ratchov Exp $ */ /* * Copyright (c) 2012 Alexandre Ratchov <alex@caoua.org> * @@ -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); |