From e8e9f79eec00768ba677c4584f4717fa41dfa886 Mon Sep 17 00:00:00 2001 From: nu774 Date: Sun, 20 Oct 2013 23:55:23 +0900 Subject: [PATCH] reimplement int16 conversion as pcm_reader --- MSVC/fdkaac.vcxproj | 1 + Makefile.am | 15 ++++--- src/lpcm.c | 11 ++--- src/lpcm.h | 2 +- src/main.c | 16 ++----- src/pcm_reader.h | 4 ++ src/pcm_sint16_converter.c | 90 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 src/pcm_sint16_converter.c diff --git a/MSVC/fdkaac.vcxproj b/MSVC/fdkaac.vcxproj index a2d139d..6d71c90 100644 --- a/MSVC/fdkaac.vcxproj +++ b/MSVC/fdkaac.vcxproj @@ -102,6 +102,7 @@ copy ..\fdk-aac\libSYS\include\machine_type.h include\fdk-aac\ + diff --git a/Makefile.am b/Makefile.am index 62d3c0c..5f8c678 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,13 +4,14 @@ AUTOMAKE_OPTIONS = subdir-objects bin_PROGRAMS = fdkaac fdkaac_SOURCES = \ - src/aacenc.c \ - src/lpcm.c \ - src/m4af.c \ - src/main.c \ - src/metadata.c \ - src/parson.c \ - src/progress.c \ + src/aacenc.c \ + src/lpcm.c \ + src/m4af.c \ + src/main.c \ + src/metadata.c \ + src/parson.c \ + src/pcm_sint16_converter.c \ + src/progress.c \ src/wav_reader.c fdkaac_LDADD = \ diff --git a/src/lpcm.c b/src/lpcm.c index 3fcb8a4..a01fed9 100644 --- a/src/lpcm.c +++ b/src/lpcm.c @@ -187,14 +187,14 @@ inline int16_t pcm_f64be_to_s16(int64_t n) int pcm_convert_to_native_sint16(const pcm_sample_description_t *format, const void *input, uint32_t nframes, - int16_t **result, uint32_t *osize) + int16_t *result) { #define CONVERT(type, conv) \ do { \ unsigned i; \ type *ip = (type *)input; \ for (i = 0; i < count; ++i) { \ - (*result)[i] = conv(ip[i]); \ + result[i] = conv(ip[i]); \ } \ } while(0) @@ -204,7 +204,7 @@ int pcm_convert_to_native_sint16(const pcm_sample_description_t *format, uint8_t *ip = (uint8_t *)input; \ bytes_per_channel = PCM_BYTES_PER_CHANNEL(format); \ for (i = 0; i < count; ++i) { \ - (*result)[i] = conv(ip); \ + result[i] = conv(ip); \ ip += bytes_per_channel; \ } \ } while(0) @@ -212,11 +212,6 @@ int pcm_convert_to_native_sint16(const pcm_sample_description_t *format, uint32_t count = nframes * format->channels_per_frame; if (!count) return 0; - if (!*result || *osize < count) { - *osize = count; - *result = realloc(*result, count * sizeof(int16_t)); - } - switch (PCM_BYTES_PER_CHANNEL(format) | format->sample_type<<4) { case 1 | PCM_TYPE_SINT<<4: CONVERT(int8_t, pcm_s8_to_s16); break; diff --git a/src/lpcm.h b/src/lpcm.h index ae67a43..8e896ae 100644 --- a/src/lpcm.h +++ b/src/lpcm.h @@ -33,5 +33,5 @@ typedef struct pcm_sample_description_t { int pcm_convert_to_native_sint16(const pcm_sample_description_t *format, const void *input, uint32_t nframes, - int16_t **result, uint32_t *osize); + int16_t *result); #endif diff --git a/src/main.c b/src/main.c index 84e910e..f4cc14c 100644 --- a/src/main.c +++ b/src/main.c @@ -493,9 +493,7 @@ int encode(pcm_reader_t *reader, HANDLE_AACENCODER encoder, uint32_t frame_length, FILE *ofp, m4af_ctx_t *m4af, int show_progress) { - uint8_t *ibuf = 0; - int16_t *pcmbuf = 0; - uint32_t pcmsize = 0; + int16_t *ibuf = 0; uint8_t *obuf = 0; uint32_t olen; uint32_t osize = 0; @@ -515,18 +513,12 @@ int encode(pcm_reader_t *reader, HANDLE_AACENCODER encoder, if ((nread = pcm_read_frames(reader, ibuf, frame_length)) < 0) { fprintf(stderr, "ERROR: read failed\n"); goto END; - } else if (nread > 0) { - if (pcm_convert_to_native_sint16(fmt, ibuf, nread, - &pcmbuf, &pcmsize) < 0) { - fprintf(stderr, "ERROR: unsupported sample format\n"); - goto END; - } } if (show_progress) aacenc_progress_update(&progress, pcm_get_position(reader), fmt->sample_rate * 2); } - if ((consumed = aac_encode_frame(encoder, fmt, pcmbuf, nread, + if ((consumed = aac_encode_frame(encoder, fmt, ibuf, nread, &obuf, &olen, &osize)) < 0) goto END; if (olen > 0) { @@ -541,7 +533,6 @@ int encode(pcm_reader_t *reader, HANDLE_AACENCODER encoder, rc = frames_written; END: if (ibuf) free(ibuf); - if (pcmbuf) free(pcmbuf); if (obuf) free(obuf); return rc; } @@ -693,8 +684,9 @@ pcm_reader_t *open_input(aacenc_param_ex_t *params) goto END; } } + return pcm_open_sint16_converter(reader); END: - return reader; + return 0; } int main(int argc, char **argv) diff --git a/src/pcm_reader.h b/src/pcm_reader.h index f8f34f7..26e7925 100644 --- a/src/pcm_reader.h +++ b/src/pcm_reader.h @@ -1,6 +1,8 @@ #ifndef PCM_READER_H #define PCM_READER_H +#include "lpcm.h" + typedef struct pcm_reader_t pcm_reader_t; typedef struct pcm_reader_vtbl_t { @@ -45,4 +47,6 @@ void pcm_teardown(pcm_reader_t **r) (*r)->vtbl->teardown(r); } +pcm_reader_t *pcm_open_sint16_converter(pcm_reader_t *reader); + #endif diff --git a/src/pcm_sint16_converter.c b/src/pcm_sint16_converter.c new file mode 100644 index 0000000..da31239 --- /dev/null +++ b/src/pcm_sint16_converter.c @@ -0,0 +1,90 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#if HAVE_STDINT_H +# include +#endif +#include "pcm_reader.h" + +typedef struct pcm_sint16_converter_t { + pcm_reader_vtbl_t *vtbl; + pcm_reader_t *src; + pcm_sample_description_t format; + void *pivot; + unsigned capacity; +} pcm_sint16_converter_t; + +static inline pcm_reader_t *get_source(pcm_reader_t *reader) +{ + return ((pcm_sint16_converter_t *)reader)->src; +} + +static const +pcm_sample_description_t *get_format(pcm_reader_t *reader) +{ + return &((pcm_sint16_converter_t *)reader)->format; +} + +static int64_t get_length(pcm_reader_t *reader) +{ + return pcm_get_length(get_source(reader)); +} + +static int64_t get_position(pcm_reader_t *reader) +{ + return pcm_get_position(get_source(reader)); +} + +static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes) +{ + 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; + self->pivot = p; + 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; + return nframes; +} + +static void teardown(pcm_reader_t **reader) +{ + pcm_sint16_converter_t *self = (pcm_sint16_converter_t *)*reader; + pcm_teardown(&self->src); + free(self->pivot); + free(self); + *reader = 0; +} + +static pcm_reader_vtbl_t my_vtable = { + get_format, get_length, get_position, read_frames, teardown +}; + +pcm_reader_t *pcm_open_sint16_converter(pcm_reader_t *reader) +{ + pcm_sint16_converter_t *self = 0; + pcm_sample_description_t *fmt; + + if ((self = calloc(1, sizeof(pcm_sint16_converter_t))) == 0) + return 0; + self->src = 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->bytes_per_frame = 2 * fmt->channels_per_frame; + return (pcm_reader_t *)self; +} -- 2.39.2