X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=src%2Fpcm_sint16_converter.c;h=052efc806af05ab374cbcc08c78ed785ef0c01e6;hb=a7e00a42195bd01fad75e5800fcbadeb1a5d3efd;hp=da31239f7796222722e21cab49888660a947e627;hpb=e8e9f79eec00768ba677c4584f4717fa41dfa886;p=fdkaac.git diff --git a/src/pcm_sint16_converter.c b/src/pcm_sint16_converter.c index da31239..052efc8 100644 --- a/src/pcm_sint16_converter.c +++ b/src/pcm_sint16_converter.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 @@ -39,10 +43,10 @@ static int64_t get_position(pcm_reader_t *reader) static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes) { + unsigned i, count; pcm_sint16_converter_t *self = (pcm_sint16_converter_t *)reader; const pcm_sample_description_t *sfmt = pcm_get_format(self->src); unsigned bytes = nframes * sfmt->bytes_per_frame; - if (self->capacity < bytes) { void *p = realloc(self->pivot, bytes); if (!p) return -1; @@ -50,8 +54,25 @@ static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes) self->capacity = bytes; } nframes = pcm_read_frames(self->src, self->pivot, nframes); - if (pcm_convert_to_native_sint16(sfmt, self->pivot, nframes, buffer) < 0) - return -1; + count = nframes * sfmt->channels_per_frame; + if (PCM_IS_FLOAT(sfmt)) { + float *ip = self->pivot; + int16_t *op = buffer; + for (i = 0; i < count; ++i) + op[i] = pcm_clip(ip[i] * 32768.0, -32768.0, 32767.0); + } else { + int32_t *ip = self->pivot; + int16_t *op = buffer; + if (sfmt->bits_per_channel <= 16) { + for (i = 0; i < count; ++i) + op[i] = ip[i] >> 16; + } else { + for (i = 0; i < count; ++i) { + int n = ((ip[i] >> 15) + 1) >> 1; + op[i] = (n == 0x8000) ? 0x7fff : n; + } + } + } return nframes; } @@ -79,12 +100,8 @@ pcm_reader_t *pcm_open_sint16_converter(pcm_reader_t *reader) self->vtbl = &my_vtable; memcpy(&self->format, pcm_get_format(reader), sizeof(self->format)); fmt = &self->format; -#if WORDS_BIGENDIAN - fmt->sample_type = PCM_TYPE_SINT_BE; -#else - fmt->sample_type = PCM_TYPE_SINT; -#endif fmt->bits_per_channel = 16; + fmt->sample_type = PCM_TYPE_SINT; fmt->bytes_per_frame = 2 * fmt->channels_per_frame; return (pcm_reader_t *)self; }