From 028bb6e60da6d97217224171996f8c6d07614468 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Fri, 27 May 2016 18:17:05 +0200 Subject: [PATCH] When resampling, use the exact resampling factor instead of the ration between input and output block sizes. This was inherited from sndion, but is not required for files because they are continuous streams of samples and do not need to be split in blocks of equal duration. This change makes playback/recording rate match exactly the requested sample rate. --- aucat/aucat.c | 4 ++-- aucat/dsp.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/aucat/aucat.c b/aucat/aucat.c index d1ac25b..4a866ab 100644 --- a/aucat/aucat.c +++ b/aucat/aucat.c @@ -311,7 +311,7 @@ slot_init(struct slot *s) xmalloc(s->round * slot_nch * sizeof(adata_t)); } if (s->afile.rate != dev_rate) { - resamp_init(&s->resamp, s->round, dev_round, + resamp_init(&s->resamp, s->afile.rate, dev_rate, slot_nch); s->resampbuf = xmalloc(dev_round * slot_nch * sizeof(adata_t)); @@ -330,7 +330,7 @@ slot_init(struct slot *s) s->cmin, s->cmax, s->cmin, s->cmax); if (s->afile.rate != dev_rate) { - resamp_init(&s->resamp, dev_round, s->round, + resamp_init(&s->resamp, dev_rate, s->afile.rate, slot_nch); s->resampbuf = xmalloc(dev_round * slot_nch * sizeof(adata_t)); diff --git a/aucat/dsp.c b/aucat/dsp.c index a1479d5..b525632 100644 --- a/aucat/dsp.c +++ b/aucat/dsp.c @@ -405,6 +405,19 @@ resamp_do(struct resamp *p, adata_t *in, adata_t *out, int icnt, int ocnt) #endif } +static unsigned int +uint_gcd(unsigned int a, unsigned int b) +{ + unsigned int r; + + while (b > 0) { + r = a % b; + a = b; + b = r; + } + return a; +} + /* * initialize resampler with ibufsz/obufsz factor and "nch" channels */ @@ -412,7 +425,22 @@ void resamp_init(struct resamp *p, unsigned int iblksz, unsigned int oblksz, int nch) { - unsigned int i; + unsigned int i, g; + + /* + * reduice iblksz/oblksz fraction + */ + g = uint_gcd(iblksz, oblksz); + iblksz /= g; + oblksz /= g; + + /* + * ensure weired rates dont cause integer overflows + */ + while (iblksz > ADATA_UNIT || oblksz > ADATA_UNIT) { + iblksz >>= 1; + oblksz >>= 1; + } p->iblksz = iblksz; p->oblksz = oblksz;