diff options
| -rw-r--r-- | .gitignore | 28 | ||||
| -rw-r--r-- | ChangeLog | 17 | ||||
| -rw-r--r-- | Makefile.am | 215 | ||||
| -rw-r--r-- | aac-enc.c | 234 | ||||
| -rwxr-xr-x | autogen.sh | 2 | ||||
| -rw-r--r-- | configure.ac | 38 | ||||
| -rw-r--r-- | fdk-aac.pc.in | 11 | ||||
| -rw-r--r-- | fdk-aac.sym | 18 | ||||
| -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/intensity.cpp | 9 | ||||
| -rw-r--r-- | m4/.gitkeep | 0 | ||||
| -rw-r--r-- | wavreader.c | 163 | ||||
| -rw-r--r-- | wavreader.h | 37 | 
15 files changed, 795 insertions, 3 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a882555 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +*.o +*.lo +*.la +.deps +.libs +.dirstamp +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..b895989 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,17 @@ +0.1.2 + - Fix a few more crashes + - Include dependency libs (such as -lm) in the pkg-config file + +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/autogen.sh b/autogen.sh new file mode 100755 index 0000000..210ccb8 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,2 @@ +#!/bin/sh +autoreconf -fiv diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..4fd969e --- /dev/null +++ b/configure.ac @@ -0,0 +1,38 @@ +dnl                                               -*- Autoconf -*- +dnl Process this file with autoconf to produce a configure script. + +AC_INIT([fdk-aac], [0.1.2], [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:3:0 + +AS_IF([test x$enable_shared = xyes], [LIBS_PRIVATE=$LIBS], [LIBS_PUBLIC=$LIBS]) +AC_SUBST(FDK_AAC_VERSION) +AC_SUBST(LIBS_PUBLIC) +AC_SUBST(LIBS_PRIVATE) + +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..2edac45 --- /dev/null +++ b/fdk-aac.pc.in @@ -0,0 +1,11 @@ +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 @LIBS_PUBLIC@ +Libs.private: @LIBS_PRIVATE@ +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.h b/libAACenc/src/aacenc.h index 87fc3e8..ed167c2 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 49f8225..95c08b3 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -1818,6 +1818,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; @@ -1871,7 +1876,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 559a4ce..99ed2b5 100644 --- a/libAACenc/src/channel_map.cpp +++ b/libAACenc/src/channel_map.cpp @@ -157,6 +157,18 @@ static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabWav[] =       { MODE_7_1_FRONT_CENTER,        { 2, 6, 7, 0, 1, 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  */ @@ -182,8 +194,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/intensity.cpp b/libAACenc/src/intensity.cpp index 6d807f7..3807233 100644 --- a/libAACenc/src/intensity.cpp +++ b/libAACenc/src/intensity.cpp @@ -593,6 +593,7 @@ void FDKaacEnc_IntensityStereoProcessing(    FIXP_DBL realIsScale[MAX_GROUPED_SFB];    INTENSITY_PARAMETERS isParams;    INT isMask[MAX_GROUPED_SFB]; +  INT lastValIs = 0, delta;    FDKmemclear((void*)isBook,sfbCnt*sizeof(INT));    FDKmemclear((void*)isMask,sfbCnt*sizeof(INT)); @@ -748,6 +749,14 @@ void FDKaacEnc_IntensityStereoProcessing(          isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)+FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1));        } +      delta = isScale[sfb+sfboffs] - lastValIs; +      if (delta < -CODE_BOOK_SCF_LAV) { +          isScale[sfb+sfboffs] = lastValIs - CODE_BOOK_SCF_LAV; +      } else if (delta + CODE_BOOK_SCF_LAV >= (INT)(sizeof(FDKaacEnc_huff_ltabscf)/sizeof(FDKaacEnc_huff_ltabscf[0]))) { +          isScale[sfb+sfboffs] = lastValIs + sizeof(FDKaacEnc_huff_ltabscf)/sizeof(FDKaacEnc_huff_ltabscf[0]) - CODE_BOOK_SCF_LAV - 1; +      } +      lastValIs = isScale[sfb+sfboffs]; +        sfbEnergyRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f);        sfbEnergyLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-1.0f);        sfbThresholdRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); 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 + | 
