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.
This commit is contained in:
Alexandre Ratchov 2016-05-27 18:17:05 +02:00
parent b347c52869
commit 028bb6e60d
2 changed files with 31 additions and 3 deletions

View File

@ -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));

View File

@ -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;