summaryrefslogtreecommitdiff
path: root/usr.bin/aucat
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2016-06-07 06:11:33 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2016-06-07 06:11:33 +0000
commit3a506d1eb7b6731c6f22862e19865bc0bdd6fd43 (patch)
tree3073fa3dd475f720c257c051b859a0863a4a66d0 /usr.bin/aucat
parent5a0bb33064ebc97a938c6637c52cd3362261d455 (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.
Diffstat (limited to 'usr.bin/aucat')
-rw-r--r--usr.bin/aucat/aucat.c34
-rw-r--r--usr.bin/aucat/dsp.c57
-rw-r--r--usr.bin/aucat/dsp.h5
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);