diff options
-rw-r--r-- | .gitignore | 27 | ||||
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | Makefile.am | 215 | ||||
-rw-r--r-- | aac-enc.c | 234 | ||||
-rw-r--r-- | configure.ac | 34 | ||||
-rw-r--r-- | fdk-aac.pc.in | 10 | ||||
-rw-r--r-- | fdk-aac.sym | 18 | ||||
-rw-r--r-- | libAACenc/src/aacEnc_ram.cpp | 2 | ||||
-rw-r--r-- | libAACenc/src/aacenc.h | 3 | ||||
-rw-r--r-- | libAACenc/src/aacenc_lib.cpp | 7 | ||||
-rw-r--r-- | libAACenc/src/channel_map.cpp | 16 | ||||
-rw-r--r-- | libAACenc/src/quantize.cpp | 10 | ||||
-rw-r--r-- | libSYS/include/machine_type.h | 2 | ||||
-rw-r--r-- | m4/.gitkeep | 0 | ||||
-rw-r--r-- | wavreader.c | 163 | ||||
-rw-r--r-- | wavreader.h | 37 |
16 files changed, 784 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..387e07b --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +*.o +*.lo +*.la +.deps +.libs +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +configure +fdk-aac.pc +config.guess +config.log +config.status +config.sub +depcomp +install-sh +libtool +ltmain.sh +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +missing +stamp-h1 +aac-enc diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..9e6eaa1 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,13 @@ +0.1.1 + - Updated to a new upstream version from Android 4.2, fixing a lot of crashes + - Cleanup of autotools usage + - Make sure the shared library links to libm if necessary + - Performance improvements on x86 + - Added support for WG4/DVD audio channel mappings + - Minimized the differences to upstream + - Added an example encoder tool + +0.1.0 + - Initial release of fdk-aac + - autotools based build system + - Enable setting VBR bitrate modes diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..e995b0a --- /dev/null +++ b/Makefile.am @@ -0,0 +1,215 @@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = subdir-objects + +AM_CPPFLAGS = \ + -I$(top_srcdir)/libAACdec/include \ + -I$(top_srcdir)/libAACenc/include \ + -I$(top_srcdir)/libSBRdec/include \ + -I$(top_srcdir)/libSBRenc/include \ + -I$(top_srcdir)/libMpegTPDec/include \ + -I$(top_srcdir)/libMpegTPEnc/include \ + -I$(top_srcdir)/libSYS/include \ + -I$(top_srcdir)/libFDK/include \ + -I$(top_srcdir)/libPCMutils/include + +AM_CXXFLAGS = -fno-exceptions -fno-rtti +libfdk_aac_la_LINK = $(LINK) $(libfdk_aac_la_LDFLAGS) +# Mention a dummy pure C file to trigger generation of the $(LINK) variable +nodist_EXTRA_libfdk_aac_la_SOURCES = dummy.c + +fdk_aacincludedir = $(includedir)/fdk-aac +fdk_aacinclude_HEADERS = \ + $(top_srcdir)/libSYS/include/machine_type.h \ + $(top_srcdir)/libSYS/include/genericStds.h \ + $(top_srcdir)/libSYS/include/FDK_audio.h \ + $(top_srcdir)/libAACenc/include/aacenc_lib.h \ + $(top_srcdir)/libAACdec/include/aacdecoder_lib.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = fdk-aac.pc + +lib_LTLIBRARIES = libfdk-aac.la + +libfdk_aac_la_LDFLAGS = -version-info @FDK_AAC_VERSION@ -no-undefined \ + -export-symbols $(top_srcdir)/fdk-aac.sym + +if EXAMPLE +bin_PROGRAMS = aac-enc$(EXEEXT) + +aac_enc_LDADD = libfdk-aac.la +aac_enc_SOURCES = aac-enc.c wavreader.c + +noinst_HEADERS = wavreader.h +endif + +AACDEC_SRC = \ + libAACdec/src/aacdec_drc.cpp \ + libAACdec/src/aacdec_hcr.cpp \ + libAACdec/src/aacdecoder.cpp \ + libAACdec/src/aacdec_pns.cpp \ + libAACdec/src/aac_ram.cpp \ + libAACdec/src/block.cpp \ + libAACdec/src/channelinfo.cpp \ + libAACdec/src/ldfiltbank.cpp \ + libAACdec/src/rvlcbit.cpp \ + libAACdec/src/rvlc.cpp \ + libAACdec/src/aacdec_hcr_bit.cpp \ + libAACdec/src/aacdec_hcrs.cpp \ + libAACdec/src/aacdecoder_lib.cpp \ + libAACdec/src/aacdec_tns.cpp \ + libAACdec/src/aac_rom.cpp \ + libAACdec/src/channel.cpp \ + libAACdec/src/conceal.cpp \ + libAACdec/src/pulsedata.cpp \ + libAACdec/src/rvlcconceal.cpp \ + libAACdec/src/stereo.cpp + +AACENC_SRC = \ + libAACenc/src/aacenc.cpp \ + libAACenc/src/aacEnc_ram.cpp \ + libAACenc/src/band_nrg.cpp \ + libAACenc/src/block_switch.cpp \ + libAACenc/src/grp_data.cpp \ + libAACenc/src/metadata_main.cpp \ + libAACenc/src/pre_echo_control.cpp \ + libAACenc/src/quantize.cpp \ + libAACenc/src/tonality.cpp \ + libAACenc/src/aacenc_hcr.cpp \ + libAACenc/src/aacEnc_rom.cpp \ + libAACenc/src/bandwidth.cpp \ + libAACenc/src/channel_map.cpp \ + libAACenc/src/intensity.cpp \ + libAACenc/src/ms_stereo.cpp \ + libAACenc/src/psy_configuration.cpp \ + libAACenc/src/sf_estim.cpp \ + libAACenc/src/transform.cpp \ + libAACenc/src/aacenc_lib.cpp \ + libAACenc/src/aacenc_tns.cpp \ + libAACenc/src/bit_cnt.cpp \ + libAACenc/src/chaosmeasure.cpp \ + libAACenc/src/line_pe.cpp \ + libAACenc/src/noisedet.cpp \ + libAACenc/src/psy_main.cpp \ + libAACenc/src/spreading.cpp \ + libAACenc/src/aacenc_pns.cpp \ + libAACenc/src/adj_thr.cpp \ + libAACenc/src/bitenc.cpp \ + libAACenc/src/dyn_bits.cpp \ + libAACenc/src/metadata_compressor.cpp \ + libAACenc/src/pnsparam.cpp \ + libAACenc/src/qc_main.cpp + +FDK_SRC = \ + libFDK/src/autocorr2nd.cpp \ + libFDK/src/dct.cpp \ + libFDK/src/FDK_bitbuffer.cpp \ + libFDK/src/FDK_core.cpp \ + libFDK/src/FDK_crc.cpp \ + libFDK/src/FDK_hybrid.cpp \ + libFDK/src/FDK_tools_rom.cpp \ + libFDK/src/FDK_trigFcts.cpp \ + libFDK/src/fft.cpp \ + libFDK/src/fft_rad2.cpp \ + libFDK/src/fixpoint_math.cpp \ + libFDK/src/mdct.cpp \ + libFDK/src/qmf.cpp \ + libFDK/src/scale.cpp + +MPEGTPDEC_SRC = \ + libMpegTPDec/src/tpdec_adif.cpp \ + libMpegTPDec/src/tpdec_adts.cpp \ + libMpegTPDec/src/tpdec_asc.cpp \ + libMpegTPDec/src/tpdec_latm.cpp \ + libMpegTPDec/src/tpdec_lib.cpp + +MPEGTPENC_SRC = \ + libMpegTPEnc/src/tpenc_adif.cpp \ + libMpegTPEnc/src/tpenc_adts.cpp \ + libMpegTPEnc/src/tpenc_asc.cpp \ + libMpegTPEnc/src/tpenc_latm.cpp \ + libMpegTPEnc/src/tpenc_lib.cpp + +PCMUTILS_SRC = \ + libPCMutils/src/pcmutils_lib.cpp + +SBRDEC_SRC = \ + libSBRdec/src/env_calc.cpp \ + libSBRdec/src/env_dec.cpp \ + libSBRdec/src/env_extr.cpp \ + libSBRdec/src/huff_dec.cpp \ + libSBRdec/src/lpp_tran.cpp \ + libSBRdec/src/psbitdec.cpp \ + libSBRdec/src/psdec.cpp \ + libSBRdec/src/psdec_hybrid.cpp \ + libSBRdec/src/sbr_crc.cpp \ + libSBRdec/src/sbr_deb.cpp \ + libSBRdec/src/sbr_dec.cpp \ + libSBRdec/src/sbrdec_drc.cpp \ + libSBRdec/src/sbrdec_freq_sca.cpp \ + libSBRdec/src/sbrdecoder.cpp \ + libSBRdec/src/sbr_ram.cpp \ + libSBRdec/src/sbr_rom.cpp + +SBRENC_SRC = \ + libSBRenc/src/bit_sbr.cpp \ + libSBRenc/src/env_bit.cpp \ + libSBRenc/src/fram_gen.cpp \ + libSBRenc/src/mh_det.cpp \ + libSBRenc/src/ps_bitenc.cpp \ + libSBRenc/src/ps_encode.cpp \ + libSBRenc/src/resampler.cpp \ + libSBRenc/src/sbr_encoder.cpp \ + libSBRenc/src/sbr_ram.cpp \ + libSBRenc/src/ton_corr.cpp \ + libSBRenc/src/code_env.cpp \ + libSBRenc/src/env_est.cpp \ + libSBRenc/src/invf_est.cpp \ + libSBRenc/src/nf_est.cpp \ + libSBRenc/src/ps_main.cpp \ + libSBRenc/src/sbrenc_freq_sca.cpp \ + libSBRenc/src/sbr_misc.cpp \ + libSBRenc/src/sbr_rom.cpp \ + libSBRenc/src/tran_det.cpp + +SYS_SRC = \ + libSYS/src/cmdl_parser.cpp \ + libSYS/src/conv_string.cpp \ + libSYS/src/genericStds.cpp \ + libSYS/src/wav_file.cpp + +libfdk_aac_la_SOURCES = \ + $(AACDEC_SRC) $(AACENC_SRC) \ + $(MPEGTPDEC_SRC) $(MPEGTPENC_SRC) \ + $(SBRDEC_SRC) $(SBRENC_SRC) \ + $(PCMUTILS_SRC) $(FDK_SRC) $(SYS_SRC) + +EXTRA_DIST = \ + $(top_srcdir)/NOTICE \ + $(top_srcdir)/Android.mk \ + $(top_srcdir)/fdk-aac.sym \ + $(top_srcdir)/documentation/*.pdf \ + $(top_srcdir)/libAACdec/src/*.h \ + $(top_srcdir)/libAACdec/src/arm/*.cpp \ + $(top_srcdir)/libAACenc/src/*.h \ + $(top_srcdir)/libSBRenc/src/*.h \ + $(top_srcdir)/libSBRenc/include/*.h \ + $(top_srcdir)/libSBRdec/src/*.h \ + $(top_srcdir)/libSBRdec/src/arm/*.cpp \ + $(top_srcdir)/libSBRdec/include/*.h \ + $(top_srcdir)/libSYS/include/*.h \ + $(top_srcdir)/libSYS/src/linux/*.cpp \ + $(top_srcdir)/libSYS/src/mips/*.cpp \ + $(top_srcdir)/libPCMutils/include/*.h \ + $(top_srcdir)/libMpegTPEnc/include/*.h \ + $(top_srcdir)/libMpegTPEnc/src/*.h \ + $(top_srcdir)/libMpegTPEnc/src/version \ + $(top_srcdir)/libMpegTPDec/include/*.h \ + $(top_srcdir)/libMpegTPDec/src/*.h \ + $(top_srcdir)/libMpegTPDec/src/version \ + $(top_srcdir)/libFDK/include/*.h \ + $(top_srcdir)/libFDK/include/arm/*.h \ + $(top_srcdir)/libFDK/include/mips/*.h \ + $(top_srcdir)/libFDK/include/x86/*.h \ + $(top_srcdir)/libFDK/src/arm/*.cpp \ + $(top_srcdir)/libFDK/src/mips/*.cpp + diff --git a/aac-enc.c b/aac-enc.c new file mode 100644 index 0000000..1528881 --- /dev/null +++ b/aac-enc.c @@ -0,0 +1,234 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2011 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include <stdio.h> +#include <stdint.h> +#include <unistd.h> +#include <stdlib.h> +#include "libAACenc/include/aacenc_lib.h" +#include "wavreader.h" + +void usage(const char* name) { + fprintf(stderr, "%s [-r bitrate] [-t aot] [-a afterburner] [-s sbr] [-v vbr] in.wav out.aac\n", name); + fprintf(stderr, "Supported AOTs:\n"); + fprintf(stderr, "\t2\tAAC-LC\n"); + fprintf(stderr, "\t5\tHE-AAC\n"); + fprintf(stderr, "\t29\tHE-AAC v2\n"); + fprintf(stderr, "\t23\tAAC-LD\n"); + fprintf(stderr, "\t39\tAAC-ELD\n"); +} + +int main(int argc, char *argv[]) { + int bitrate = 64000; + int ch; + const char *infile, *outfile; + FILE *out; + void *wav; + int format, sample_rate, channels, bits_per_sample; + int input_size; + uint8_t* input_buf; + int16_t* convert_buf; + int aot = 2; + int afterburner = 1; + int eld_sbr = 0; + int vbr = 0; + HANDLE_AACENCODER handle; + CHANNEL_MODE mode; + AACENC_InfoStruct info = { 0 }; + while ((ch = getopt(argc, argv, "r:t:a:s:v:")) != -1) { + switch (ch) { + case 'r': + bitrate = atoi(optarg); + break; + case 't': + aot = atoi(optarg); + break; + case 'a': + afterburner = atoi(optarg); + break; + case 's': + eld_sbr = atoi(optarg); + break; + case 'v': + vbr = atoi(optarg); + break; + case '?': + default: + usage(argv[0]); + return 1; + } + } + if (argc - optind < 2) { + usage(argv[0]); + return 1; + } + infile = argv[optind]; + outfile = argv[optind + 1]; + + wav = wav_read_open(infile); + if (!wav) { + fprintf(stderr, "Unable to open wav file %s\n", infile); + return 1; + } + if (!wav_get_header(wav, &format, &channels, &sample_rate, &bits_per_sample, NULL)) { + fprintf(stderr, "Bad wav file %s\n", infile); + return 1; + } + if (format != 1) { + fprintf(stderr, "Unsupported WAV format %d\n", format); + return 1; + } + if (bits_per_sample != 16) { + fprintf(stderr, "Unsupported WAV sample depth %d\n", bits_per_sample); + return 1; + } + switch (channels) { + case 1: mode = MODE_1; break; + case 2: mode = MODE_2; break; + case 3: mode = MODE_1_2; break; + case 4: mode = MODE_1_2_1; break; + case 5: mode = MODE_1_2_2; break; + case 6: mode = MODE_1_2_2_1; break; + default: + fprintf(stderr, "Unsupported WAV channels %d\n", channels); + return 1; + } + if (aacEncOpen(&handle, 0, channels) != AACENC_OK) { + fprintf(stderr, "Unable to open encoder\n"); + return 1; + } + if (aacEncoder_SetParam(handle, AACENC_AOT, aot) != AACENC_OK) { + fprintf(stderr, "Unable to set the AOT\n"); + return 1; + } + if (aot == 39 && eld_sbr) { + if (aacEncoder_SetParam(handle, AACENC_SBR_MODE, 1) != AACENC_OK) { + fprintf(stderr, "Unable to set SBR mode for ELD\n"); + return 1; + } + } + if (aacEncoder_SetParam(handle, AACENC_SAMPLERATE, sample_rate) != AACENC_OK) { + fprintf(stderr, "Unable to set the AOT\n"); + return 1; + } + if (aacEncoder_SetParam(handle, AACENC_CHANNELMODE, mode) != AACENC_OK) { + fprintf(stderr, "Unable to set the channel mode\n"); + return 1; + } + if (aacEncoder_SetParam(handle, AACENC_CHANNELORDER, 1) != AACENC_OK) { + fprintf(stderr, "Unable to set the wav channel order\n"); + return 1; + } + if (vbr) { + if (aacEncoder_SetParam(handle, AACENC_BITRATEMODE, vbr) != AACENC_OK) { + fprintf(stderr, "Unable to set the VBR bitrate mode\n"); + return 1; + } + } else { + if (aacEncoder_SetParam(handle, AACENC_BITRATE, bitrate) != AACENC_OK) { + fprintf(stderr, "Unable to set the bitrate\n"); + return 1; + } + } + if (aacEncoder_SetParam(handle, AACENC_TRANSMUX, 2) != AACENC_OK) { + fprintf(stderr, "Unable to set the ADTS transmux\n"); + return 1; + } + if (aacEncoder_SetParam(handle, AACENC_AFTERBURNER, afterburner) != AACENC_OK) { + fprintf(stderr, "Unable to set the afterburner mode\n"); + return 1; + } + if (aacEncEncode(handle, NULL, NULL, NULL, NULL) != AACENC_OK) { + fprintf(stderr, "Unable to initialize the encoder\n"); + return 1; + } + if (aacEncInfo(handle, &info) != AACENC_OK) { + fprintf(stderr, "Unable to get the encoder info\n"); + return 1; + } + + out = fopen(outfile, "wb"); + if (!out) { + perror(outfile); + return 1; + } + + input_size = channels*2*info.frameLength; + input_buf = (uint8_t*) malloc(input_size); + convert_buf = (int16_t*) malloc(input_size); + + while (1) { + AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 }; + AACENC_InArgs in_args = { 0 }; + AACENC_OutArgs out_args = { 0 }; + int in_identifier = IN_AUDIO_DATA; + int in_size, in_elem_size; + int out_identifier = OUT_BITSTREAM_DATA; + int out_size, out_elem_size; + int read, i; + void *in_ptr, *out_ptr; + uint8_t outbuf[20480]; + AACENC_ERROR err; + + read = wav_read_data(wav, input_buf, input_size); + for (i = 0; i < read/2; i++) { + const uint8_t* in = &input_buf[2*i]; + convert_buf[i] = in[0] | (in[1] << 8); + } + if (read <= 0) { + in_args.numInSamples = -1; + } else { + in_ptr = convert_buf; + in_size = read; + in_elem_size = 2; + + in_args.numInSamples = read/2; + in_buf.numBufs = 1; + in_buf.bufs = &in_ptr; + in_buf.bufferIdentifiers = &in_identifier; + in_buf.bufSizes = &in_size; + in_buf.bufElSizes = &in_elem_size; + } + out_ptr = outbuf; + out_size = sizeof(outbuf); + out_elem_size = 1; + out_buf.numBufs = 1; + out_buf.bufs = &out_ptr; + out_buf.bufferIdentifiers = &out_identifier; + out_buf.bufSizes = &out_size; + out_buf.bufElSizes = &out_elem_size; + + if ((err = aacEncEncode(handle, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) { + if (err == AACENC_ENCODE_EOF) + break; + fprintf(stderr, "Encoding failed\n"); + return 1; + } + if (out_args.numOutBytes == 0) + continue; + fwrite(outbuf, 1, out_args.numOutBytes, out); + } + free(input_buf); + free(convert_buf); + fclose(out); + wav_read_close(wav); + aacEncClose(&handle); + + return 0; +} + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..c52d0b9 --- /dev/null +++ b/configure.ac @@ -0,0 +1,34 @@ +dnl -*- Autoconf -*- +dnl Process this file with autoconf to produce a configure script. + +AC_INIT([fdk-aac], [0.1.1], [http://sourceforge.net/projects/opencore-amr/]) +AC_CONFIG_AUX_DIR(.) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([tar-ustar foreign]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +dnl Various options for configure +AC_ARG_ENABLE([example], + [AS_HELP_STRING([--enable-example], + [enable example encoding program (default is no)])], + [example=$enableval], [example=no]) + +dnl Automake conditionals to set +AM_CONDITIONAL(EXAMPLE, test x$example = xyes) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CXX +LT_INIT + +AC_CHECK_LIB([m], [sin]) + +dnl soname version to use +dnl goes by ‘current[:revision[:age]]’ with the soname ending up as +dnl current.age.revision +FDK_AAC_VERSION=0:2:0 +AC_SUBST(FDK_AAC_VERSION) + +AC_CONFIG_FILES([Makefile + fdk-aac.pc]) +AC_OUTPUT diff --git a/fdk-aac.pc.in b/fdk-aac.pc.in new file mode 100644 index 0000000..50fa1d5 --- /dev/null +++ b/fdk-aac.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Fraunhofer FDK AAC Codec Library +Description: AAC codec library +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lfdk-aac +Cflags: -I${includedir} diff --git a/fdk-aac.sym b/fdk-aac.sym new file mode 100644 index 0000000..2a06c41 --- /dev/null +++ b/fdk-aac.sym @@ -0,0 +1,18 @@ +aacDecoder_AncDataGet +aacDecoder_AncDataInit +aacDecoder_Close +aacDecoder_ConfigRaw +aacDecoder_DecodeFrame +aacDecoder_Fill +aacDecoder_GetFreeBytes +aacDecoder_GetLibInfo +aacDecoder_GetStreamInfo +aacDecoder_Open +aacDecoder_SetParam +aacEncClose +aacEncEncode +aacEncGetLibInfo +aacEncInfo +aacEncOpen +aacEncoder_GetParam +aacEncoder_SetParam diff --git a/libAACenc/src/aacEnc_ram.cpp b/libAACenc/src/aacEnc_ram.cpp index 9366235..45bca93 100644 --- a/libAACenc/src/aacEnc_ram.cpp +++ b/libAACenc/src/aacEnc_ram.cpp @@ -95,7 +95,7 @@ amm-info@iis.fraunhofer.de #include "aacEnc_ram.h" - C_ALLOC_MEM (AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE/sizeof(FIXP_DBL)) + C_AALLOC_MEM (AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE/sizeof(FIXP_DBL)) /* Static memory areas, must not be overwritten in other sections of the decoder ! diff --git a/libAACenc/src/aacenc.h b/libAACenc/src/aacenc.h index 942f686..517b0dc 100644 --- a/libAACenc/src/aacenc.h +++ b/libAACenc/src/aacenc.h @@ -173,7 +173,8 @@ typedef enum { typedef enum { CH_ORDER_MPEG = 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */ - CH_ORDER_WAV /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR) */ + CH_ORDER_WAV, /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR) */ + CH_ORDER_WG4 /*!< WG4 fileformat channel ordering (e. g. 5.1: L, R, SL, SR, C, LFE) */ } CHANNEL_ORDER; diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 07cfddc..a4291d5 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -1599,6 +1599,11 @@ AACENC_ERROR aacEncoder_SetParam( if (settings->userBitrateMode != value) { switch ( value ) { case 0: + case 1: + case 2: + case 3: + case 4: + case 5: case 8: settings->userBitrateMode = value; hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; @@ -1652,7 +1657,7 @@ AACENC_ERROR aacEncoder_SetParam( break; case AACENC_CHANNELORDER: if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) { - if (! ((value==0) || (value==1)) ) { + if (! ((value==0) || (value==1) || (value==2)) ) { err = AACENC_INVALID_CONFIG; break; } diff --git a/libAACenc/src/channel_map.cpp b/libAACenc/src/channel_map.cpp index 687ed83..6eddd47 100644 --- a/libAACenc/src/channel_map.cpp +++ b/libAACenc/src/channel_map.cpp @@ -153,6 +153,18 @@ static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabWav[] = { MODE_1_2_2_2_1, { 2, 0, 1, 6, 7, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ }; +static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabWg4[] = +{ + { MODE_INVALID, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* invalid */ + { MODE_1, { 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* mono */ + { MODE_2, { 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* stereo */ + { MODE_1_2, { 2, 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 3ch */ + { MODE_1_2_1, { 3, 0, 1, 2,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 4ch */ + { MODE_1_2_2, { 4, 0, 1, 2, 3,-1,-1,-1,-1,-1,-1,-1} }, /* 5ch */ + { MODE_1_2_2_1, { 4, 0, 1, 2, 3, 5,-1,-1,-1,-1,-1,-1} }, /* 5.1ch */ + { MODE_1_2_2_2_1, { 6, 0, 1, 2, 3, 4, 5, 7,-1,-1,-1,-1} }, /* 7.1ch */ +}; + /* Channel mode configuration tab provides, corresponding number of channels and elements */ @@ -176,8 +188,10 @@ const INT* FDKaacEnc_getChannelAssignment(CHANNEL_MODE encMode, CHANNEL_ORDER co if (co == CH_ORDER_MPEG) pTab = assignmentInfoTabMpeg; - else + else if (co == CH_ORDER_WAV) pTab = assignmentInfoTabWav; + else + pTab = assignmentInfoTabWg4; for(i=MAX_MODES-1; i>0; i--) { if (encMode== pTab[i].encoderMode) { diff --git a/libAACenc/src/quantize.cpp b/libAACenc/src/quantize.cpp index a1698a8..1f7402b 100644 --- a/libAACenc/src/quantize.cpp +++ b/libAACenc/src/quantize.cpp @@ -127,7 +127,10 @@ static void FDKaacEnc_quantizeLines(INT gain, accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); totalShift = (16-4)-(3*(totalShift>>2)); FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ - accu>>=totalShift; + if (totalShift < 32) + accu>>=totalShift; + else + accu = 0; quaSpectrum[line] = (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS-1-16))); } else if(accu > FL2FXCONST_DBL(0.0f)) @@ -140,7 +143,10 @@ static void FDKaacEnc_quantizeLines(INT gain, accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); totalShift = (16-4)-(3*(totalShift>>2)); FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ - accu>>=totalShift; + if (totalShift < 32) + accu>>=totalShift; + else + accu = 0; quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS-1-16)); } else diff --git a/libSYS/include/machine_type.h b/libSYS/include/machine_type.h index b5642b2..d04a8e8 100644 --- a/libSYS/include/machine_type.h +++ b/libSYS/include/machine_type.h @@ -173,7 +173,7 @@ amm-info@iis.fraunhofer.de /* Define 64 bit base integer type. */ -#ifdef _WIN32 +#ifdef _MSC_VER typedef __int64 INT64; typedef unsigned __int64 UINT64; #else diff --git a/m4/.gitkeep b/m4/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/m4/.gitkeep diff --git a/wavreader.c b/wavreader.c new file mode 100644 index 0000000..f672001 --- /dev/null +++ b/wavreader.c @@ -0,0 +1,163 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#include "wavreader.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) + +struct wav_reader { + FILE *wav; + uint32_t data_length; + + int format; + int sample_rate; + int bits_per_sample; + int channels; + int byte_rate; + int block_align; +}; + +static uint32_t read_tag(struct wav_reader* wr) { + uint32_t tag = 0; + tag = (tag << 8) | fgetc(wr->wav); + tag = (tag << 8) | fgetc(wr->wav); + tag = (tag << 8) | fgetc(wr->wav); + tag = (tag << 8) | fgetc(wr->wav); + return tag; +} + +static uint32_t read_int32(struct wav_reader* wr) { + uint32_t value = 0; + value |= fgetc(wr->wav) << 0; + value |= fgetc(wr->wav) << 8; + value |= fgetc(wr->wav) << 16; + value |= fgetc(wr->wav) << 24; + return value; +} + +static uint16_t read_int16(struct wav_reader* wr) { + uint16_t value = 0; + value |= fgetc(wr->wav) << 0; + value |= fgetc(wr->wav) << 8; + return value; +} + +void* wav_read_open(const char *filename) { + struct wav_reader* wr = (struct wav_reader*) malloc(sizeof(*wr)); + long data_pos = 0; + memset(wr, 0, sizeof(*wr)); + + wr->wav = fopen(filename, "rb"); + if (wr->wav == NULL) { + free(wr); + return NULL; + } + + while (1) { + uint32_t tag, tag2, length; + tag = read_tag(wr); + if (feof(wr->wav)) + break; + length = read_int32(wr); + if (tag != TAG('R', 'I', 'F', 'F') || length < 4) { + fseek(wr->wav, length, SEEK_CUR); + continue; + } + tag2 = read_tag(wr); + length -= 4; + if (tag2 != TAG('W', 'A', 'V', 'E')) { + fseek(wr->wav, length, SEEK_CUR); + continue; + } + // RIFF chunk found, iterate through it + while (length >= 8) { + uint32_t subtag, sublength; + subtag = read_tag(wr); + if (feof(wr->wav)) + break; + sublength = read_int32(wr); + length -= 8; + if (length < sublength) + break; + if (subtag == TAG('f', 'm', 't', ' ')) { + if (sublength < 16) { + // Insufficient data for 'fmt ' + break; + } + wr->format = read_int16(wr); + wr->channels = read_int16(wr); + wr->sample_rate = read_int32(wr); + wr->byte_rate = read_int32(wr); + wr->block_align = read_int16(wr); + wr->bits_per_sample = read_int16(wr); + fseek(wr->wav, sublength - 16, SEEK_CUR); + } else if (subtag == TAG('d', 'a', 't', 'a')) { + data_pos = ftell(wr->wav); + wr->data_length = sublength; + fseek(wr->wav, sublength, SEEK_CUR); + } else { + fseek(wr->wav, sublength, SEEK_CUR); + } + length -= sublength; + } + if (length > 0) { + // Bad chunk? + fseek(wr->wav, length, SEEK_CUR); + } + } + fseek(wr->wav, data_pos, SEEK_SET); + return wr; +} + +void wav_read_close(void* obj) { + struct wav_reader* wr = (struct wav_reader*) obj; + fclose(wr->wav); + free(wr); +} + +int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length) { + struct wav_reader* wr = (struct wav_reader*) obj; + if (format) + *format = wr->format; + if (channels) + *channels = wr->channels; + if (sample_rate) + *sample_rate = wr->sample_rate; + if (bits_per_sample) + *bits_per_sample = wr->bits_per_sample; + if (data_length) + *data_length = wr->data_length; + return wr->format && wr->sample_rate; +} + +int wav_read_data(void* obj, unsigned char* data, unsigned int length) { + struct wav_reader* wr = (struct wav_reader*) obj; + int n; + if (wr->wav == NULL) + return -1; + if (length > wr->data_length) + length = wr->data_length; + n = fread(data, 1, length, wr->wav); + wr->data_length -= length; + return n; +} + diff --git a/wavreader.h b/wavreader.h new file mode 100644 index 0000000..57a13ff --- /dev/null +++ b/wavreader.h @@ -0,0 +1,37 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2009 Martin Storsjo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ + +#ifndef WAVREADER_H +#define WAVREADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +void* wav_read_open(const char *filename); +void wav_read_close(void* obj); + +int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length); +int wav_read_data(void* obj, unsigned char* data, unsigned int length); + +#ifdef __cplusplus +} +#endif + +#endif + |