X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=src%2Fextrapolater.c;h=b09347817658afe58328cbf891af03416bfa1985;hb=b54538f79e8180499baa7d88325733102e061bc5;hp=22b0f129d9e39a05b337040c626b910ddb83a15a;hpb=4d48b091d49818772a47559ba7fd7ab58fdd7682;p=fdkaac.git diff --git a/src/extrapolater.c b/src/extrapolater.c index 22b0f12..b093478 100644 --- a/src/extrapolater.c +++ b/src/extrapolater.c @@ -1,3 +1,7 @@ +/* + * Copyright (C) 2013 nu774 + * For conditions of distribution and use, see copyright notice in COPYING + */ #if HAVE_CONFIG_H # include "config.h" #endif @@ -82,11 +86,11 @@ static int fetch(extrapolater_t *self, unsigned nframes) if (realloc_buffer(bp, nframes * sfmt->bytes_per_frame) == 0) { rc = pcm_read_frames(self->src, bp->data, nframes); - bp->count = rc > 0 ? rc : 0; + if (rc > 0) bp->count = rc; } if (rc > 0) self->nbuffer ^= 1; - return bp->count; + return rc <= 0 ? 0 : bp->count; } static int extrapolate(extrapolater_t *self, const buffer_t *bp, @@ -122,7 +126,13 @@ static int process0(extrapolater_t *self, void *buffer, unsigned nframes) reverse_buffer(buffer, nframes, nchannels); reverse_buffer(bp->data, bp->count, nchannels); } - self->process = bp->count ? process1 : process2; + if (bp->count) + self->process = process1; + else { + memset(bp->data, 0, nframes * sfmt->bytes_per_frame); + bp->count = nframes; + self->process = process2; + } return nframes; } @@ -133,8 +143,27 @@ static int process1(extrapolater_t *self, void *buffer, unsigned nframes) assert(bp->count <= nframes); memcpy(buffer, bp->data, bp->count * sfmt->bytes_per_frame); - if (!fetch(self, nframes)) + if (!fetch(self, nframes)) { + buffer_t *bbp = &self->buffer[self->nbuffer]; + if (bp->count < 2 * LPC_ORDER) { + size_t total = bp->count + bbp->count; + if (bbp->count && + realloc_buffer(bbp, total * sfmt->bytes_per_frame) == 0 && + realloc_buffer(bp, total * sfmt->bytes_per_frame) == 0) + { + memcpy(bbp->data + bbp->count * sfmt->channels_per_frame, + bp->data, bp->count * sfmt->bytes_per_frame); + memcpy(bp->data, bbp->data, total * sfmt->bytes_per_frame); + bp->count = total; + } + } + if (bp->count >= 2 * LPC_ORDER) + extrapolate(self, bp, bbp->data, nframes); + else + memset(bbp->data, 0, nframes * sfmt->bytes_per_frame); + bbp->count = nframes; self->process = process2; + } return bp->count; } @@ -142,27 +171,15 @@ static int process2(extrapolater_t *self, void *buffer, unsigned nframes) { const pcm_sample_description_t *sfmt = pcm_get_format(self->src); buffer_t *bp = &self->buffer[self->nbuffer]; - buffer_t *bbp = &self->buffer[self->nbuffer ^ 1]; - - if (bp->count < 2 * LPC_ORDER) { - size_t total = bp->count + bbp->count; - if (bbp->count && - realloc_buffer(bbp, total * sfmt->bytes_per_frame) == 0) - { - memcpy(bbp->data + bbp->count * sfmt->channels_per_frame, - bp->data, bp->count * sfmt->bytes_per_frame); - bbp->count = total; - bp->count = 0; - bp = bbp; - self->nbuffer ^= 1; - } - } - self->process = process3; - - if (bp->count >= 2 * LPC_ORDER) - extrapolate(self, bp, buffer, nframes); - else - memset(buffer, 0, nframes * sfmt->bytes_per_frame); + if (bp->count < nframes) + nframes = bp->count; + memcpy(buffer, bp->data, nframes * sfmt->bytes_per_frame); + if (bp->count > nframes) + memmove(bp->data, bp->data + nframes * sfmt->channels_per_frame, + (bp->count - nframes) * sfmt->bytes_per_frame); + bp->count -= nframes; + if (bp->count == 0) + self->process = process3; return nframes; }