Compare commits

...

105 Commits

Author SHA1 Message Date
Martin Storsjo
5fd7e6537d Merge remote-tracking branch 'aosp/master' 2016-10-28 10:26:20 +03:00
Martin Storsjo
2b1e8db04d Don't force C++98 mode any longer
The code builds fine in C++11 mode now.
2016-10-18 08:29:04 +03:00
Martin Storsjo
55554d0b2d Merge remote-tracking branch 'aosp/master' 2016-10-18 08:28:51 +03:00
Martin Storsjo
cb57d89522 Add new files to "make dist" 2016-09-24 13:36:43 +03:00
Martin Storsjo
72037da0ba Fix building with MSVC for ARM
cmnintrin.h only existed for Windows CE, and doesn't seem to actually
be necessary for building this.
2016-09-11 13:28:47 +03:00
Martin Storsjo
45915b67e4 Detect MSVC x64 2016-09-11 13:28:44 +03:00
opcodevoid
6ac0611b07 Windows MSVC Makefile 2016-09-11 13:28:30 +03:00
Martin Storsjo
5eb3c9be88 Merge remote-tracking branch 'aosp/master' 2016-09-10 14:38:15 +03:00
Lexyan
1d686c3a23 Add aarch64 assembly optimization (ARMv8a 64 bits)
The fixmuldiv functions don't need inline assembly to be fast
in this architecture; the compiler (both clang and GCC) figure
out to use the optimal instructions for this (which is 2 instruction
sequence), and when letting the compiler emit the instructions
instead of using inline assembly, the compiler is able to
interleave those instructions with other instructions,
improving scheduling, making it even faster than when using
inline assembly.

Overall, this gives about 50% speedup.
2016-09-10 14:33:39 +03:00
Martin Storsjo
a0bd8aa3b6 Bump the package version to 0.1.5 2016-08-25 22:20:09 +03:00
Martin Storsjo
932fc12396 Update Makefile.am with newly added and removed files 2016-08-25 22:14:25 +03:00
Martin Storsjo
1ce312b1dc Bump the library versions in the headers 2016-08-25 22:13:16 +03:00
Martin Storsjo
f9d0f65e65 Merge remote-tracking branch 'aosp/master' 2016-08-25 22:12:15 +03:00
Martin Storsjo
15b128dd82 Explicitly force building in C++98 mode
GCC 6 defaults to C++14 (or more precisely, gnu++14) instead of C++98
(or gnu++98).

The fdk-aac source doesn't support being built in this mode at the
moment, since it relies on narrowing conversion from unsigned 32 bit
integers to FIXP_DBL (which is a signed data type of the same size).

The same approach is used upstream in Android as well, since
d52f3747683.

This fixes buliding with GCC 6.
2016-05-18 10:13:31 +03:00
Martin Storsjo
8fe6faf261 Merge remote-tracking branch 'aosp/master' 2016-05-18 09:36:12 +03:00
Guillaume Smaha
f132ac5f3d Invert inline and void to be compatible with gcc 3.3.4 2016-05-18 08:07:32 +02:00
Guillaume Smaha
112fe2c68d Fix issue with gcc 3.4.3 which doesn't support always_inline without inline 2016-05-17 15:39:10 +02:00
Martin Storsjo
50a98d1fd2 Merge remote-tracking branch 'aosp/master' 2016-03-09 08:49:40 +02:00
Martin Storsjo
0943e715f7 Remove android specific diagnostic logging 2016-01-26 22:42:09 +02:00
Timothy Gu
c8ad7a2ef9 Merge remote-tracking branch 'aosp/master' into update 2016-01-26 11:57:49 -08:00
Vicente Olivert Riera
047376af8c libFDK/include/mips/cplx_mul.h: use C code instead of ASM
Replace the assembler code by the equivalent in C. This way it will work
for every MIPS ISA. Now the check for __mips_isa_rev < 6 is no longer
necessary, so remove it.

Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
2015-09-21 11:59:02 +01:00
Jasper Lievisse Adriaanse
2585f10da2 Fix the preprocessor statements controlling the use of mips{32,64}r1 instructions.
Only enable code using mips32/mips64 instructions if the compiler is targetting
this ISA. (integer madd and msub instructions aren't available in the
``canonical'' mips ISAs)
2015-08-13 10:53:07 +02:00
Martin Storsjo
83ac4a9860 Merge remote-tracking branch 'aosp/master' 2015-03-11 16:49:43 +02:00
Martin Storsjo
2ded8da912 Update the changelog for the upcoming 0.1.4 release 2015-03-05 10:26:54 +02:00
Martin Storsjo
d7fca408b4 Merge remote-tracking branch 'aosp/master' 2015-03-03 10:52:42 +02:00
Andrew Stone
97b382cd3f Ignore file compile that is generated by autogen 2014-11-24 16:13:15 -05:00
Martin Storsjo
06ee7ef4e7 Bump the package version number to 0.1.4 2014-11-07 09:33:28 +02:00
Martin Storsjo
a0bfb7ee7c Bump the shared library major number
The AAC_PCM_OUTPUT_CHANNELS option no longer exists under the
same name nor enum value any longer, and the AUDIO_CHANNEL_TYPE
enum has been changed in a way which may break users.
2014-11-07 09:33:28 +02:00
Martin Storsjo
63447a9993 Include the decoder API version in the public header 2014-11-07 09:33:28 +02:00
Martin Storsjo
69a488faf2 Include the new file limiter.cpp in the build 2014-11-07 09:33:28 +02:00
Martin Storsjo
6ccecbc4b0 Merge remote-tracking branch 'aosp/master' 2014-11-07 09:32:48 +02:00
Martin Storsjo
ce1863444a Include libFDK ppc headers in make dist 2014-11-04 23:48:42 +02:00
Martin Storsjo
9a3234055a Extend the GetInvInt table to 80 elements
This is a bug fix patch from Fraunhofer, amending/replacing/extending
the previous commit which only extended the table to 55 elements.
(In my previous fix, 55 seemed to be enough for the issue at hand at
least. A few of the coefficients had slightly different rounding than
what Fraunhofer had used though).

This will show up in AOSP in the next code drop as well.
2014-08-01 10:36:54 +03:00
Martin Storsjo
6522e87ad6 Extend GetInvInt to support values up to 54
For sample rates >= 64 kHz with short blocks, the largest sfb
width is 36, which after grouping can be multiplied with 3,
ending up as 108. GetInvInt needs to be able to support
the largest grouped sfb width, divided by two (3 * 36 / 2 = 54).

This fixes VBR encoding with sample rates >= 64 kHz.
2014-07-29 15:00:56 +03:00
Martin Storsjo
f82510410d Add support for waveformatex files
This is used for multichannel wave files.
2014-06-23 10:45:50 +03:00
Martin Storsjo
16f75a570e Support reading sox style piped wav files
Sox writes the RIFF header size as a very large number, instead
of as 0 as in libavformat.
2014-06-23 10:45:50 +03:00
Martin Storsjo
43cb942cd4 Use skip instead of fseek
fseek(SEEK_CUR) doesn't work for nonseekable streams (such
as pipes).

Only do this for skipping past small chunks; don't use it for
skipping past the actual data for non-streamed input.
2014-06-23 10:45:50 +03:00
Martin Storsjo
cb19aa7c12 Allow reading wav files with a 0 bytes RIFF chunk
This is required in order to read streamed wav files produced by
the libavformat wav muxer.
2014-06-23 10:45:50 +03:00
Martin Storsjo
3951d0a4e5 Allow opening stdin when "-" is specified 2014-06-23 10:45:50 +03:00
Martin Storsjo
e7348e7a5d Support streamed wav files with a 0 bytes data chunk 2014-06-23 10:45:50 +03:00
Martin Storsjo
1652691ee9 Use AC_SEARCH_LIBS to search for a library containing math functions
Even though the previous mechanism worked, this should be more
correct.
2014-06-23 10:44:02 +03:00
Mark Harris
b8f6c140ce Fix AIX build
Fix AIX build failure with IBM xlC compiler due to conflicting
definition of M_PI.  The libSYS/include/genericStds.h definition is
guarded with #ifndef M_PI, but was included before <math.h> which
defines M_PI with more significant digits.
2014-05-26 12:31:40 -07:00
Mark Harris
c15b653b99 Add ppc optimization for clz and fixmul
Optimize ppc/ppc64 similar to i386/x86_64, approximately doubling
encoding speed on a Power Mac G5 running OS X 10.5.8.
2014-05-26 12:23:56 -07:00
Mark Harris
5e154c7ed1 Make LONG 32 bits for ppc64 as it is for x86_64 2014-05-26 12:14:40 -07:00
Mark Harris
72fd73dbdd Fix PowerPC Mac build 2014-05-26 12:12:03 -07:00
Martin Storsjo
2f29dd48d0 Bump the version number, add a changelog entry 2013-11-25 12:25:55 +02:00
Martin Storsjo
c3f7404aab Include autogen.sh when building distribution packages 2013-11-25 12:25:55 +02:00
Martin Storsjo
164fc98be1 Include the encoder library version in the publicly installed header
This allows callers to conditionally use new API features without
breaking compatibility with the earlier versions of the library.
2013-11-01 12:11:30 +02:00
Martin Storsjo
c8002b04ff Avoid casting arbitrary values to an enum
The enum only contains the constant values 0, 1 and 2. This produces
the warning "comparison of constant 6 with expression of type
'PS_RESOLUTION' is always false" in clang for the first check
in the getNoBands function (but apparently not for the second one
even though mode>=3 shouldn't ever happen for a valid PS_RESOLUTION
value either). This could allow the compiler to completely remove
the conditions that shouldn't be able to occur even though they
actually are used and are necessary.

By passing the value as UINT instead, it is clear to the compiler
that all the checks are necessary.
2013-11-01 11:28:59 +02:00
Martin Storsjo
b41a6f9e81 Revert "Avoid too big changes in isScale"
This reverts commit 226601a8d9bce81455e161a0e26051d2f22c5d7a.

This change doesn't seem to be necessary any longer, a proper
fix seems to be included upstream now in
60a27b7fe5bf2c3b07ae7f679ca67c0c5cba3b00.
2013-11-01 10:58:46 +02:00
Martin Storsjo
321233ee92 Merge remote-tracking branch 'aosp/kitkat-release' into kitkat-merge
Conflicts:
	libAACenc/src/quantize.cpp
2013-11-01 10:46:40 +02:00
Martin Storsjo
fcb5f1b692 Ignore .dirstamp files 2013-10-03 09:02:22 +02:00
Terrance
0feb581efb Add an autogen shellscript 2013-09-07 18:32:50 +03:00
Martin Storsjo
f6aebfd487 Bump the version number, add a changelog entry 2013-07-27 18:54:00 +03:00
Martin Storsjo
59ff381ee4 Include dependency libs (-lm) in the pkg-config file 2013-07-27 02:01:33 +03:00
Martin Storsjo
a63897ce4e Check the right element in isBook
This makes sure we read the right array element, corresponding
to all other array accesses in the same function, and all other
use of the isBook array elsewhere in the library.

This makes the fix in the previous commit ("Avoid too big changes
in isScale") work as intended, fixing other samples that triggered
assertions.
2013-07-10 17:21:42 +03:00
Martin Storsjo
226601a8d9 Avoid too big changes in isScale
These values are delta encoded, but only steps [-60,60] are
possible to encode. If the difference between two values are
bigger than that, we end up with a sequence we are unable to
encode.

This fixes crashes on certain stereo samples at higher
bitrates.
2013-03-18 16:28:50 +02:00
Martin Storsjo
bae4553d42 Merge remote-tracking branch 'aosp/master' 2013-02-27 22:06:16 +02:00
Martin Storsjo
8f9f42c104 Don't try to shift more bits than the variable length
Shifting by more than (or equal to) the variable length is
undefined in C.

This caused the quantized spectrum values to remain unshifted,
causing loud beeps in some samples.

The exact same change was originally applied in
657456949 (for AOSP) and in 24021f190 (in the separate fdk-aac
repo), but was overwritten and silently reverted by the new
upstream code drop for Android 4.2 in 381d69840a. After the code
drop, I chose not to reapply this change since the crashes that
it fixed had been fixed in other ways upstream and I was unable to
reproduce them after the new code drop.
2013-02-17 02:21:26 +02:00
Martin Storsjo
b966edf7fc Add a changelog entry for 0.1.1, bump the version numbers 2012-11-13 23:47:12 +02:00
Martin Storsjo
ec5d922893 Rename sbr_rom/ram files back to the original names
This minimizes the differences to upstream.
2012-11-02 13:30:45 +02:00
Martin Storsjo
53b442d8af build: Build object files in subdirectories
This allows producing more than one object file with the same name.
2012-11-02 12:47:43 +02:00
Martin Storsjo
dc409c50e6 build: Don't use make variables in the declaration of source files
This is required for working dependency generation with
the subdir-objects option enabled.
2012-11-02 12:45:29 +02:00
Martin Storsjo
9285c096fe Revert "Use __builtin_clz instead of default implementation of fixnormz on GCC"
This reverts commit e036dbc8eb7d5fdd02dc70faff20e9ac3e2989ca.

Upstream took __builtin_clz in use (in the new header
libFDK/include/x86/clz_x86.h, together with an alternative
implementation for MSVC), so this change can be dropped to
minimize the differences.
2012-11-01 11:30:58 +02:00
Martin Storsjo
48cfc02cbf Revert parts of "Use saturating adds to avoid overflow"
This reverts commit 839ae290c1f5a263613bea1a5fde863e757a8849.

This change is no longer necessary on top of the new upstream,
I cannot reproduce the crash that this fixed with the new upstream.
2012-11-01 11:30:40 +02:00
Martin Storsjo
dc0de33e86 Only use __int64 on MSVC, not on all win32 compilers
Mingw32 doesn't define the __int64 types.

This was implicitly reverted in AOSP (where this change was
already merged before) by the new code drop from Fraunhofer.
2012-11-01 11:30:40 +02:00
Martin Storsjo
961d5598d3 Update Makefile.am to account for a removed file in the latest upstream 2012-11-01 11:17:22 +02:00
Martin Storsjo
54dfe1ec69 Merge remote-tracking branch 'aosp/jb-mr1-release' into master
Conflicts:
	libAACenc/src/band_nrg.cpp
	libAACenc/src/grp_data.cpp
	libSBRenc/src/env_est.cpp
2012-11-01 11:08:03 +02:00
Jeffrey Knockel
fea3c1d0ff Make sure AACdynamic_RAM gets allocated aligned to 8 bytes
This fixes assert failures on platforms where malloc doesn't provide
8 byte alignment, such as Win9x.
2012-10-25 12:14:05 +03:00
Sergio Ammirata
790bf9f088 Add support for Workgroup 4 (WG4) channel mapping
This is the channel ordering used in DVD Audio, and is the standard
used internally in the VLC media player.
2012-10-05 12:17:37 +03:00
Martin Storsjo
e79b172ba6 Revert "Do schur_div with a direct 64 bit division instead of a loop on x86"
This reverts commit 923f3e95f3e332d26f03cf6782f0ab61596ceef2.

The optimized version differed from the original in a few cases
(in some cases where the return value turned out to be negative
while the original implementation returned a positive value),
so revert it for now until it has been analyzed completely.
2012-09-14 11:10:29 +03:00
Martin Storsjo
bf0d9ddc43 Add an encoder example 2012-09-13 23:27:27 +03:00
Jakub Stachowski
923f3e95f3 Do schur_div with a direct 64 bit division instead of a loop on x86
This speeds up HE-AACv2 encoding from 3.85 s to 3.42 s on a Core i7.
2012-09-09 22:18:09 +03:00
Martin Storsjo
50b1de17ac Merge remote-tracking branch 'aosp/master' 2012-09-05 11:32:25 +03:00
Martin Storsjo
8e4d5d9d2f Use a saturating shift to avoid overflow
When the shift overflowed, asserts were triggered later, where
the values were assumed to be non-negative.
2012-09-02 22:27:52 +02:00
Jakub Stachowski
e036dbc8eb Use __builtin_clz instead of default implementation of fixnormz on GCC
The library contains architecture specific versions of the clz functions
for arm and mips, but the fallback C version for other architectures is
pretty slow.

By using __builtin_clz on GCC (available since GCC 3.4), we get a
significant (20-40 %) speedup of the total running time on x86.

Speed difference: 5.1 s instead of 8.6 s for AAC-LC 128 kbit/s and
3.8 s instead of 4.9 s for HE-AACv2 32 kbit/s, on an i7.
2012-08-14 23:48:55 +03:00
Martin Storsjo
6999980d67 Use saturating adds to avoid overflow
When the addition overflowed, asserts were triggered later, where
the values were assumed to be non-negative.
2012-08-11 22:28:54 +03:00
Martin Storsjo
010c75901e Use saturating adds in all other similar loops in groupShortData as well 2012-08-10 11:21:10 +03:00
Martin Storsjo
24021f1909 Don't try to shift more bits than the variable length
Shifting by more than (or equal to) the variable length is
undefined in C.
2012-08-10 11:01:37 +03:00
Martin Storsjo
839ae290c1 Use saturating adds to avoid overflow
These additions can overflow, triggering assertions later.
2012-08-10 11:01:36 +03:00
Martin Storsjo
d8e8f1ac46 Merge remote-tracking branch 'aosp/master' 2012-08-08 22:19:49 +03:00
Martin Storsjo
c44084453d Check whether we need to link to -lm for math functions 2012-07-14 01:58:51 +03:00
Diego Elio Pettenò
bb34df82cf build: update libtool reference to version 2. 2012-07-11 22:13:08 +03:00
Diego Elio Pettenò
b9c682b9d3 build: declare the project foreign to automake
By default automake thinks the project is part of GNU and enforces the
presence of some files. By declaring the project foreign, we can
remove the 0-sized files.
2012-07-11 22:13:08 +03:00
Diego Elio Pettenò
be5ecc95c4 build: ignore autotools support files, and remove them from the repository.
Change-Id: Icc9c9ded1142232b5030183f2a653ee7cef632b5
2012-07-11 22:13:08 +03:00
Diego Elio Pettenò
a0b3294e55 build: do not use config.h 2012-07-11 07:48:52 -07:00
Diego Elio Pettenò
40f4e738e4 build: use dnl for comments in configure.ac
This simply means the comments are not copied into the executed
configure script.
2012-07-11 07:45:09 -07:00
Diego Elio Pettenò
df77638da1 build: do not call AC_CANONICAL_HOST.
Unless configure uses $host there is no reason to call it directly.
2012-07-11 07:44:13 -07:00
Martin Storsjo
78443185d4 Export the external symbols via the libtool -export-symbols option
Change-Id: If139d0d1cf6f9fdfb0ebc477d2152b9f5f49f566
2012-07-11 14:37:36 +03:00
Martin Storsjo
7ed64e79d4 Only use __int64 on MSVC, not on all win32 compilers
Mingw32 doesn't define the __int64 types.
2012-07-11 14:28:03 +03:00
Martin Storsjo
c8776d228b Update the changelog 2012-07-11 14:28:03 +03:00
Martin Storsjo
4f7355002c Don't link to libstdc++
While the source is C++, it doesn't use anything from the C++
runtime, so by building with -fno-exceptions -fno-rtti, the
dynamic library doesn't have to be linked to libstdc++. This
also simplifies things for users of the static library.
2012-07-11 14:28:03 +03:00
Martin Storsjo
b431d100a3 Allow setting bitrate modes 1-5 too
These correspond to different VBR modes.
2012-07-11 14:28:03 +03:00
Martin Storsjo
7e5a3465a8 Ignore generated files 2012-07-11 14:28:03 +03:00
Martin Storsjo
27360036f6 Add files added by "automake --add-missing -c" 2012-07-11 14:28:03 +03:00
Martin Storsjo
28ca63087f Add an _enc suffix to the sbr_ram/rom files in libSBRenc
This avoids name clashes with the similarly named files in
libSBRdec, when building all libraries with one single
automake file.
2012-07-11 14:28:03 +03:00
Martin Storsjo
ce9492073b Add COPYING as a symlink to NOTICE 2012-07-11 14:28:03 +03:00
Martin Storsjo
6cae68113f Add stub documents required by autotools 2012-07-11 14:28:02 +03:00
Martin Storsjo
f4fc1a43e4 Run "libtoolize -c" 2012-07-11 14:28:02 +03:00
Martin Storsjo
cd1c375de0 Add automake/autoconf source files
Change-Id: If97c7482bffaab4a21cd2fb8341f2939f19d3bbd
2012-07-11 14:28:02 +03:00
Dave Burke
2bda038c16 Add NOTICE file. Rework make file so it appears in settings.
Change-Id: I9d9ab17121e2db58f8a4ba4b40e14cab629b1a7e
2012-06-12 10:34:26 -07:00
Dave Burke
18a4af02f9 Added license boilerplate to all source files.
Change-Id: I42a702487e6db4953dca0027710ea4fe266052fd
Also:
 - Removed dead code in several source files.
 - Minor changes in comments.
 - No functional changes. No changes in executed code.
 - Added documentation PDFs.
2012-06-11 20:07:04 -07:00
Dave Burke
698b536f3b Update to 2012_05_11 version.
Fixes:
- Don't throw error for invalid bitrate but limit to functional value
- More robust ASC parsing
- More robust handling of corrupt bitstreams
- Handle multiple raw access units

Change-Id: Ib49fe2545ff4185fe924126da702fe84ac5c2d87
2012-05-12 13:47:46 -07:00
Dave Burke
9bf37cc971 Fraunhofer AAC codec.
License boilerplate update to follow.

Change-Id: I2810460c11a58b6d148d84673cc031f3685e79b5
2012-04-17 23:04:43 -07:00
Anatol Pomazau
a37315fe10 Initial empty repository 2012-04-06 11:04:36 -07:00
30 changed files with 2498 additions and 50 deletions

29
.gitignore vendored Normal file
View File

@ -0,0 +1,29 @@
*.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
compile

30
ChangeLog Normal file
View File

@ -0,0 +1,30 @@
0.1.4
- Updated upstream sources, with minor changes to the decoder API
breaking the ABI. (Calling code using AUDIO_CHANNEL_TYPE may need to
be updated. A new option AAC_PCM_LIMITER_ENABLE has been added, enabled
by default, which incurs extra decoding delay.)
- PowerPC optimizations, fixes for building on AIX
- Support for reading streamed wav files in the encoder example
- Fix VBR encoding of sample rates over 64 kHz
0.1.3
- Updated upstream sources, with a number of crash fixes and new features
(including support for encoding 7.1)
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

222
Makefile.am Normal file
View File

@ -0,0 +1,222 @@
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_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_drm.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/limiter.cpp \
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)/autogen.sh \
$(top_srcdir)/MODULE_LICENSE_FRAUNHOFER \
$(top_srcdir)/NOTICE \
$(top_srcdir)/Android.mk \
$(top_srcdir)/fdk-aac.sym \
$(top_srcdir)/Makefile.vc \
$(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/aarch64/*.h \
$(top_srcdir)/libFDK/include/arm/*.h \
$(top_srcdir)/libFDK/include/mips/*.h \
$(top_srcdir)/libFDK/include/ppc/*.h \
$(top_srcdir)/libFDK/include/x86/*.h \
$(top_srcdir)/libFDK/src/arm/*.cpp \
$(top_srcdir)/libFDK/src/mips/*.cpp \
$(top_srcdir)/win32/*.h

250
Makefile.vc Normal file
View File

@ -0,0 +1,250 @@
#
# Options:
# prefix=\path\to\install
#
# Compiling: nmake -f Makefile.vc
# Installing: nmake -f Makefile.vc prefix=\path\to\x install
#
VERSION=0.1.5
# Linker and librarian commands
LD = link
AR = lib
!IFDEF HOME
# In case we are using a cross compiler shell.
MKDIR_FLAGS = -p
!ENDIF
AM_CPPFLAGS = \
-Iwin32 \
-IlibAACdec/include \
-IlibAACenc/include \
-IlibSBRdec/include \
-IlibSBRenc/include \
-IlibMpegTPDec/include \
-IlibMpegTPEnc/include \
-IlibSYS/include \
-IlibFDK/include \
-IlibPCMutils/include
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_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_drm.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/limiter.cpp \
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_SOURCES = \
$(AACDEC_SRC) $(AACENC_SRC) \
$(MPEGTPDEC_SRC) $(MPEGTPENC_SRC) \
$(SBRDEC_SRC) $(SBRENC_SRC) \
$(PCMUTILS_SRC) $(FDK_SRC) $(SYS_SRC)
aac_enc_SOURCES = aac-enc.c wavreader.c
prefix = \usr\local
prefix_win = $(prefix:/=\) # In case we are using MSYS or MinGW.
CFLAGS = /nologo /W3 /Ox /MT /EHsc /Dinline=__inline $(TARGET_FLAGS) $(AM_CPPFLAGS) $(XCFLAGS)
CXXFLAGS = $(CFLAGS)
CPPFLAGS = $(CFLAGS)
LDFLAGS = -nologo $(XLDFLAGS)
ARFLAGS = -nologo
incdir = $(prefix_win)\include\fdk-aac
bindir = $(prefix_win)\bin
libdir = $(prefix_win)\lib
INST_DIRS = $(bindir) $(incdir) $(libdir)
LIB_DEF = fdk-aac.def
STATIC_LIB = fdk-aac.lib
SHARED_LIB = fdk-aac-1.dll
IMP_LIB = fdk-aac.dll.lib
AAC_ENC_OBJS = $(aac_enc_SOURCES:.c=.obj)
FDK_OBJS = $(libfdk_aac_SOURCES:.cpp=.obj)
PROGS = aac-enc.exe
all: $(LIB_DEF) $(STATIC_LIB) $(SHARED_LIB) $(IMP_LIB) $(PROGS)
clean:
del /f $(LIB_DEF) $(STATIC_LIB) $(SHARED_LIB) $(IMP_LIB) $(PROGS) libfdk-aac.pc 2>NUL
del /f *.obj *.exp 2>NUL
del /f libAACdec\src\*.obj 2>NUL
del /f libAACenc\src\*.obj 2>NUL
del /f libFDK\src\*.obj 2>NUL
del /f libMpegTPDec\src\*.obj 2>NUL
del /f libMpegTPEnc\src\*.obj 2>NUL
del /f libPCMutils\src\*.obj 2>NUL
del /f libSBRdec\src\*.obj 2>NUL
del /f libSBRenc\src\*.obj 2>NUL
del /f libSYS\src\*.obj 2>NUL
install: $(INST_DIRS)
copy libAACdec\include\aacdecoder_lib.h $(incdir)
copy libAACenc\include\aacenc_lib.h $(incdir)
copy libSYS\include\FDK_audio.h $(incdir)
copy libSYS\include\genericStds.h $(incdir)
copy libSYS\include\machine_type.h $(incdir)
copy $(STATIC_LIB) $(libdir)
copy $(IMP_LIB) $(libdir)
copy $(SHARED_LIB) $(bindir)
copy $(PROGS) $(bindir)
copy $(LIB_DEF) $(libdir)
$(INST_DIRS):
@mkdir $(MKDIR_FLAGS) $@
$(STATIC_LIB): $(FDK_OBJS)
$(AR) $(ARFLAGS) -out:$@ $(FDK_OBJS)
$(IMP_LIB): $(SHARED_LIB)
$(SHARED_LIB): $(FDK_OBJS)
$(LD) $(LDFLAGS) -OUT:$@ -DEF:$(LIB_DEF) -implib:$(IMP_LIB) -DLL $(FDK_OBJS)
$(PROGS): $(AAC_ENC_OBJS)
$(LD) $(LDFLAGS) -out:$@ $(AAC_ENC_OBJS) $(STATIC_LIB)
.cpp.obj:
$(CXX) $(CXXFLAGS) -c -Fo$@ $<
$(LIB_DEF):
@echo EXPORTS > $(LIB_DEF)
@type fdk-aac.sym >> $(LIB_DEF)

240
aac-enc.c Normal file
View File

@ -0,0 +1,240 @@
/* ------------------------------------------------------------------
* 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>
#if defined(_MSC_VER)
#include <getopt.h>
#else
#include <unistd.h>
#endif
#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;
}

2
autogen.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
autoreconf -fiv

38
configure.ac Normal file
View File

@ -0,0 +1,38 @@
dnl -*- Autoconf -*-
dnl Process this file with autoconf to produce a configure script.
AC_INIT([fdk-aac], [0.1.5], [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_SEARCH_LIBS([sin], [m])
dnl soname version to use
dnl goes by current[:revision[:age]] with the soname ending up as
dnl current.age.revision
FDK_AAC_VERSION=1:0: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

11
fdk-aac.pc.in Normal file
View File

@ -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}

18
fdk-aac.sym Normal file
View File

@ -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

View File

@ -348,6 +348,10 @@ Where N equals to CStreamInfo::frameSize .
#include "genericStds.h"
#define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 5
#define AACDECODER_LIB_VL2 17
/**
* \brief AAC decoder error codes.
*/

View File

@ -705,6 +705,9 @@ the encoder deactivates PNS calculation internally.
#include "machine_type.h"
#include "FDK_audio.h"
#define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4
#define AACENCODER_LIB_VL2 22
/**
* AAC encoder error codes.

View File

@ -178,7 +178,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;

View File

@ -1865,7 +1865,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;
}

View File

@ -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) {

View File

@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de
/* Take action against VisualStudio 2005 crosscompile problems. */
/* Use single macro (the GCC built in macro) for architecture identification independent of the particular toolchain */
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || (defined(_MSC_VER) && defined(_M_IX86)) || defined (__x86_64__)
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || (defined(_MSC_VER) && defined(_M_IX86)) || defined (__x86_64__) || (defined(_MSC_VER) && defined(_M_X64))
#define __x86__
#endif
@ -107,6 +107,10 @@ amm-info@iis.fraunhofer.de
#define __arm__
#endif
#if defined(_ARCH_PPC) && !defined(__powerpc__)
#define __powerpc__ 1
#endif
/* Define __ARM_ARCH_5TE__ if armv5te features are supported */
@ -150,7 +154,6 @@ amm-info@iis.fraunhofer.de
#endif
#ifdef _M_ARM
#include "cmnintrin.h"
#include "armintr.h"
#endif
@ -158,7 +161,7 @@ amm-info@iis.fraunhofer.de
/* Define preferred Multiplication type */
#if defined(FDK_HIGH_PERFORMANCE) && !defined(FDK_HIGH_QUALITY) /* FDK_HIGH_PERFORMANCE */
#if defined(__mips__) || defined(__powerpc__) || defined(__sh__)
#if defined(__mips__) || defined(__sh__)
#define ARCH_PREFER_MULT_16x16
#undef SINETABLE_16BIT
#undef POW2COEFF_16BIT
@ -194,6 +197,14 @@ amm-info@iis.fraunhofer.de
#undef POW2COEFF_16BIT
#undef LDCOEFF_16BIT
#elif defined(__aarch64__) || defined(__AARCH64EL__)
#define ARCH_PREFER_MULT_32x32
#define ARCH_PREFER_MULT_32x16
#define SINETABLE_16BIT
#define POW2COEFF_16BIT
#define LDCOEFF_16BIT
#define WINDOWTABLE_16BIT
#elif defined(__x86__) /* cppp replaced: elif */
#define ARCH_PREFER_MULT_32x16
#define SINETABLE_16BIT
@ -201,6 +212,14 @@ amm-info@iis.fraunhofer.de
#define POW2COEFF_16BIT
#define LDCOEFF_16BIT
#elif defined(__powerpc__)
#define ARCH_PREFER_MULT_32x32
#define ARCH_PREFER_MULT_32x16
#define SINETABLE_16BIT
#define POW2COEFF_16BIT
#define LDCOEFF_16BIT
#define WINDOWTABLE_16BIT
#else
#warning >>>> Please set architecture characterization defines for your platform (FDK_HIGH_PERFORMANCE)! <<<<

View File

@ -0,0 +1,122 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
of the MPEG specifications.
Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
individually for the purpose of encoding or decoding bit streams in products that are compliant with
the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
software may already be covered under those patent licenses when it is used for those licensed purposes only.
Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
applications information and documentation.
2. COPYRIGHT LICENSE
Redistribution and use in source and binary forms, with or without modification, are permitted without
payment of copyright license fees provided that you satisfy the following conditions:
You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
your modifications thereto in source code form.
You must retain the complete text of this software license in the documentation and/or other materials
provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
The name of Fraunhofer may not be used to endorse or promote products derived from this library without
prior written permission.
You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
software or your modifications thereto.
Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
and the date of any change. For modified versions of the FDK AAC Codec, the term
"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
3. NO PATENT LICENSE
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
respect to this software.
You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
by appropriate patent licenses.
4. DISCLAIMER
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
or business interruption, however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of this software, even if
advised of the possibility of such damage.
5. CONTACT INFORMATION
Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */
/*************************** Fraunhofer IIS FDK Tools **********************
Author(s):
Description: fixed point intrinsics
******************************************************************************/
#if defined(__aarch64__) || defined(__AARCH64EL__)
#if defined(__GNUC__)
/* aarch64 gcc*/
#define FUNCTION_fixnormz_D
#define FUNCTION_fixnorm_D
inline INT fixnormz_D(LONG value)
{
INT result;
asm("clz %w0, %w1 ": "=r"(result) : "r"(value) );
return result;
}
inline INT fixnorm_D(LONG value)
{
INT result;
if (value == 0) {
return 0;
}
if (value < 0) {
value = ~value;
}
result = fixnormz_D(value);
return result - 1;
}
#endif /* aarch64 toolchain */
#endif /* __aarch64__ */

View File

@ -0,0 +1,113 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
of the MPEG specifications.
Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
individually for the purpose of encoding or decoding bit streams in products that are compliant with
the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
software may already be covered under those patent licenses when it is used for those licensed purposes only.
Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
applications information and documentation.
2. COPYRIGHT LICENSE
Redistribution and use in source and binary forms, with or without modification, are permitted without
payment of copyright license fees provided that you satisfy the following conditions:
You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
your modifications thereto in source code form.
You must retain the complete text of this software license in the documentation and/or other materials
provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
The name of Fraunhofer may not be used to endorse or promote products derived from this library without
prior written permission.
You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
software or your modifications thereto.
Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
and the date of any change. For modified versions of the FDK AAC Codec, the term
"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
3. NO PATENT LICENSE
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
respect to this software.
You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
by appropriate patent licenses.
4. DISCLAIMER
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
or business interruption, however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of this software, even if
advised of the possibility of such damage.
5. CONTACT INFORMATION
Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */
/*************************** Fraunhofer IIS FDK Tools **********************
Author(s):
Description: fixed point intrinsics
******************************************************************************/
#if defined(__aarch64__) || defined(__AARCH64EL__)
#if defined(__GNUC__) /* cppp replaced: elif */
/* ARM with GNU compiler */
#define FUNCTION_fixmuldiv2_DD
#define FUNCTION_fixmuldiv2BitExact_DD
#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b)
#define FUNCTION_fixmulBitExact_DD
#define fixmulBitExact_DD(a,b) fixmul_DD(a,b)
inline INT fixmuldiv2_DD (const INT a, const INT b)
{
INT result ;
result = ((long long)a * b)>>32;
return result ;
}
#endif /* defined(__GNUC__) */
#endif /* __aarch64__ */

View File

@ -97,12 +97,18 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__)
#include "arm/clz_arm.h"
#elif defined(__aarch64__) || defined(__AARCH64EL__)
#include "aarch64/clz_aarch64.h"
#elif defined(__mips__) /* cppp replaced: elif */
#include "mips/clz_mips.h"
#elif defined(__x86__) /* cppp replaced: elif */
#include "x86/clz_x86.h"
#elif defined(__powerpc__)
#include "ppc/clz_ppc.h"
#endif /* all cores */

View File

@ -121,7 +121,7 @@ void ifft(int length, FIXP_DBL *pInput, INT *scalefactor);
*/
LNK_SECTION_CODE_L1
static void FORCEINLINE fft_4(FIXP_DBL *x)
static FORCEINLINE void fft_4(FIXP_DBL *x)
{
FIXP_DBL a00, a10, a20, a30, tmp0, tmp1;
@ -149,7 +149,7 @@ static void FORCEINLINE fft_4(FIXP_DBL *x)
}
LNK_SECTION_CODE_L1
static void FORCEINLINE fft_8(FIXP_DBL *x)
static FORCEINLINE void fft_8(FIXP_DBL *x)
{
#define W_PiFOURTH STC(0x5a82799a)

View File

@ -98,12 +98,18 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__)
#include "arm/fixmul_arm.h"
#elif defined(__aarch64__) || defined(__AARCH64EL__)
#include "aarch64/fixmul_aarch64.h"
#elif defined(__mips__) /* cppp replaced: elif */
#include "mips/fixmul_mips.h"
#elif defined(__x86__) /* cppp replaced: elif */
#include "x86/fixmul_x86.h"
#elif defined(__powerpc__)
#include "ppc/fixmul_ppc.h"
#endif /* all cores */
/*************************************************************************

View File

@ -89,7 +89,7 @@ amm-info@iis.fraunhofer.de
******************************************************************************/
#if defined(__GNUC__) && defined(__mips__) && __mips_isa_rev < 6
#if defined(__GNUC__) && defined(__mips__)
//#define FUNCTION_cplxMultDiv2_32x16
@ -107,24 +107,8 @@ inline void cplxMultDiv2( FIXP_DBL *c_Re,
FIXP_DBL b_Re,
FIXP_DBL b_Im)
{
INT result;
__asm__ ("mult %[a_Re], %[b_Re];\n"
"msub %[a_Im], %[b_Im];\n"
"mfhi %[result];\n"
: [result]"=r"(result)
: [a_Re]"d"(a_Re), [b_Re]"d"(b_Re), [a_Im]"d"(a_Im), [b_Im]"d"(b_Im)
: "lo");
*c_Re = result;
__asm__ ("mult %[a_Re], %[b_Im];\n"
"madd %[a_Im], %[b_Re];\n"
"mfhi %[result];\n"
: [result]"=r"(result)
: [a_Re]"r"(a_Re), [b_Im]"r"(b_Im), [a_Im]"r"(a_Im), [b_Re]"r"(b_Re)
: "lo");
*c_Im = result;
*c_Re = (((long long)a_Re * (long long)b_Re) - ((long long)a_Im * (long long)b_Im))>>32;
*c_Im = (((long long)a_Re * (long long)b_Im) + ((long long)a_Im * (long long)b_Re))>>32;
}
#endif
@ -136,25 +120,8 @@ inline void cplxMult( FIXP_DBL *c_Re,
FIXP_DBL b_Re,
FIXP_DBL b_Im)
{
INT result;
__asm__ ("mult %[a_Re], %[b_Re];\n"
"msub %[a_Im], %[b_Im];\n"
"mfhi %[result];\n"
//"extr_w %[result], 31;\n"
: [result]"=r"(result)
: [a_Re]"r"(a_Re), [b_Re]"r"(b_Re), [a_Im]"r"(a_Im), [b_Im]"r"(b_Im)
: "lo");
*c_Re = result<<1;
__asm__ ("mult %[a_Re], %[b_Im];\n"
"madd %[a_Im], %[b_Re];\n"
"mfhi %[result];\n"
//"extr_w %[result], 31;\n"
: [result]"=r"(result)
: [a_Re]"r"(a_Re), [b_Im]"r"(b_Im), [a_Im]"r"(a_Im), [b_Re]"r"(b_Re)
: "lo");
*c_Im = result<<1;
*c_Re = ((((long long)a_Re * (long long)b_Re) - ((long long)a_Im * (long long)b_Im))>>32)<<1;
*c_Im = ((((long long)a_Re * (long long)b_Im) + ((long long)a_Im * (long long)b_Re))>>32)<<1;
}
#endif

View File

@ -0,0 +1,102 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
of the MPEG specifications.
Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
individually for the purpose of encoding or decoding bit streams in products that are compliant with
the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
software may already be covered under those patent licenses when it is used for those licensed purposes only.
Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
applications information and documentation.
2. COPYRIGHT LICENSE
Redistribution and use in source and binary forms, with or without modification, are permitted without
payment of copyright license fees provided that you satisfy the following conditions:
You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
your modifications thereto in source code form.
You must retain the complete text of this software license in the documentation and/or other materials
provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
The name of Fraunhofer may not be used to endorse or promote products derived from this library without
prior written permission.
You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
software or your modifications thereto.
Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
and the date of any change. For modified versions of the FDK AAC Codec, the term
"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
3. NO PATENT LICENSE
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
respect to this software.
You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
by appropriate patent licenses.
4. DISCLAIMER
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
or business interruption, however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of this software, even if
advised of the possibility of such damage.
5. CONTACT INFORMATION
Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */
/*************************** Fraunhofer IIS FDK Tools **********************
Author(s):
Description: fixed point intrinsics
******************************************************************************/
#if defined(__powerpc__) && (defined(__GNUC__) || defined(__xlC__))
#define FUNCTION_fixnormz_D
inline INT fixnormz_D(LONG value)
{
INT result;
__asm__ ("cntlzw %0, %1" : "=r" (result) : "r" (value));
return result;
}
#endif /* __powerpc__ && (__GNUC__ || __xlC__) */

View File

@ -0,0 +1,115 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
of the MPEG specifications.
Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
individually for the purpose of encoding or decoding bit streams in products that are compliant with
the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
software may already be covered under those patent licenses when it is used for those licensed purposes only.
Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
applications information and documentation.
2. COPYRIGHT LICENSE
Redistribution and use in source and binary forms, with or without modification, are permitted without
payment of copyright license fees provided that you satisfy the following conditions:
You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
your modifications thereto in source code form.
You must retain the complete text of this software license in the documentation and/or other materials
provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
The name of Fraunhofer may not be used to endorse or promote products derived from this library without
prior written permission.
You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
software or your modifications thereto.
Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
and the date of any change. For modified versions of the FDK AAC Codec, the term
"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
3. NO PATENT LICENSE
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
respect to this software.
You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
by appropriate patent licenses.
4. DISCLAIMER
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
or business interruption, however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of this software, even if
advised of the possibility of such damage.
5. CONTACT INFORMATION
Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */
/*************************** Fraunhofer IIS FDK Tools **********************
Author(s):
Description: fixed point intrinsics
******************************************************************************/
#if defined(__powerpc__) && (defined(__GNUC__) || defined(__xlC__))
#define FUNCTION_fixmuldiv2_DD
#define FUNCTION_fixmuldiv2BitExact_DD
#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b)
#define FUNCTION_fixmulBitExact_DD
#define fixmulBitExact_DD(a,b) fixmul_DD(a,b)
#define FUNCTION_fixmuldiv2BitExact_DS
#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b)
#define FUNCTION_fixmulBitExact_DS
#define fixmulBitExact_DS(a,b) fixmul_DS(a,b)
inline INT fixmuldiv2_DD (const INT a, const INT b)
{
INT result;
__asm__ ("mulhw %0, %1, %2" : "=r" (result) : "r" (a), "r" (b));
return result;
}
#endif /* __powerpc__ && (__GNUC__ || __xlC__) */

View File

@ -88,7 +88,7 @@ amm-info@iis.fraunhofer.de
expansion in the PCM time domain.
*******************************************************************************/
#include <log/log.h>
#include "pcmutils_lib.h"
#include "genericStds.h"
@ -2079,7 +2079,6 @@ PCMDMX_ERROR pcmDmx_ApplyFrame (
}
}
if (ch != numInChannels) {
ALOGE("b/23876444");
return PCMDMX_INVALID_ARGUMENT;
}

View File

@ -97,7 +97,10 @@ amm-info@iis.fraunhofer.de
#ifdef FUNCTION_LPPTRANSPOSER_func1
/* Note: This code requires only 43 cycles per iteration instead of 61 on ARM926EJ-S */
__attribute__ ((noinline)) static void lppTransposer_func1(
#ifdef __GNUC__
__attribute__ ((noinline))
#endif
static void lppTransposer_func1(
FIXP_DBL *lowBandReal,
FIXP_DBL *lowBandImag,
FIXP_DBL **qmfBufferReal,

View File

@ -293,7 +293,7 @@ amm-info@iis.fraunhofer.de
#else
#ifndef FORCEINLINE
#if defined(__GNUC__) /* cppp replaced: elif */
#define FORCEINLINE __attribute((always_inline))
#define FORCEINLINE inline __attribute((always_inline))
#else
#define FORCEINLINE
#endif

0
m4/.gitkeep Normal file
View File

193
wavreader.c Normal file
View File

@ -0,0 +1,193 @@
/* ------------------------------------------------------------------
* 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;
int streamed;
};
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;
}
static void skip(FILE *f, int n) {
int i;
for (i = 0; i < n; i++)
fgetc(f);
}
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));
if (!strcmp(filename, "-"))
wr->wav = stdin;
else
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 (!length || length >= 0x7fff0000) {
wr->streamed = 1;
length = ~0;
}
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);
if (wr->format == 0xfffe) {
if (sublength < 28) {
// Insufficient data for waveformatex
break;
}
skip(wr->wav, 8);
wr->format = read_int32(wr);
skip(wr->wav, sublength - 28);
} else {
skip(wr->wav, sublength - 16);
}
} else if (subtag == TAG('d', 'a', 't', 'a')) {
data_pos = ftell(wr->wav);
wr->data_length = sublength;
if (!wr->data_length || wr->streamed) {
wr->streamed = 1;
return wr;
}
fseek(wr->wav, sublength, SEEK_CUR);
} else {
skip(wr->wav, sublength);
}
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;
if (wr->wav != stdin)
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 && !wr->streamed)
length = wr->data_length;
n = fread(data, 1, length, wr->wav);
wr->data_length -= length;
return n;
}

37
wavreader.h Normal file
View File

@ -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

904
win32/getopt.h Normal file
View File

@ -0,0 +1,904 @@
#ifndef __GETOPT_H__
/**
* DISCLAIMER
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
*
* The mingw-w64 runtime package and its code is distributed in the hope that it
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Implementation of the `getopt', `getopt_long' and `getopt_long_only'
* APIs, for inclusion in the MinGW runtime library.
*
* This file is part of the MinGW32 package set.
*
* Written by Keith Marshall <keithmarshall@users.sourceforge.net>
* Copyright (C) 2008, 2009, 2011, 2012, MinGW.org Project.
*
* ---------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice, this permission notice, and the following
* disclaimer shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* ---------------------------------------------------------------------------
*
*/
#define __GETOPT_H__
/* All the headers include this file. */
#include <crtdefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int optind; /* index of first non-option in argv */
extern int optopt; /* single option character, as parsed */
extern int opterr; /* flag to enable built-in diagnostics... */
/* (user may set to zero, to suppress) */
extern char *optarg; /* pointer to argument of current option */
/* Identify how to get the calling program name, for use in messages...
*/
#ifdef __CYGWIN__
/*
* CYGWIN uses this DLL reference...
*/
# define PROGNAME __progname
extern char __declspec(dllimport) *__progname;
#else
/*
* ...while elsewhere, we simply use the first argument passed.
*/
# define PROGNAME *argv
#endif
extern int getopt(int nargc, char * const *nargv, const char *options);
#ifdef _BSD_SOURCE
/*
* BSD adds the non-standard `optreset' feature, for reinitialisation
* of `getopt' parsing. We support this feature, for applications which
* proclaim their BSD heritage, before including this header; however,
* to maintain portability, developers are advised to avoid it.
*/
# define optreset __mingw_optreset
extern int optreset;
#endif
#ifdef __cplusplus
}
#endif
/*
* POSIX requires the `getopt' API to be specified in `unistd.h';
* thus, `unistd.h' includes this header. However, we do not want
* to expose the `getopt_long' or `getopt_long_only' APIs, when
* included in this manner. Thus, close the standard __GETOPT_H__
* declarations block, and open an additional __GETOPT_LONG_H__
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
* to declare the extended API.
*/
#endif /* !defined(__GETOPT_H__) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__
#ifdef __cplusplus
extern "C" {
#endif
struct option /* specification for a long form option... */
{
const char *name; /* option name, without leading hyphens */
int has_arg; /* does it take an argument? */
int *flag; /* where to save its status, or NULL */
int val; /* its associated status value */
};
enum /* permitted values for its `has_arg' field... */
{
no_argument = 0, /* option never takes an argument */
required_argument, /* option always requires an argument */
optional_argument /* option may take an argument */
};
extern int getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
/*
* Previous MinGW implementation had...
*/
#ifndef HAVE_DECL_GETOPT
/*
* ...for the long form API only; keep this for compatibility.
*/
# define HAVE_DECL_GETOPT 1
#endif
/* Identify how to get the calling program name, for use in messages...
*/
#ifdef __CYGWIN__
/*
* CYGWIN uses this DLL reference...
*/
# define PROGNAME __progname
extern char __declspec(dllimport) *__progname;
#else
/*
* ...while elsewhere, we simply use the first argument passed.
*/
# define PROGNAME *argv
#endif
/* Initialise the public variables. */
int optind = 1; /* index for first non-option arg */
int opterr = 1; /* enable built-in error messages */
char *optarg = NULL; /* pointer to current option argument */
#define CHAR char /* argument type selector */
#define getopt_switchar '-' /* option prefix character in argv */
#define getopt_pluschar '+' /* prefix for POSIX mode in optstring */
#define getopt_takes_argument ':' /* marker for optarg in optstring */
#define getopt_arg_assign '=' /* longopt argument field separator */
#define getopt_unknown '?' /* return code for unmatched option */
#define getopt_ordered 1 /* return code for ordered non-option */
#define getopt_all_done -1 /* return code to indicate completion */
enum
{ /* All `getopt' API functions are implemented via calls to the
* common static function `getopt_parse()'; these `mode' selectors
* determine the behaviour of `getopt_parse()', to deliver the
* appropriate result in each case.
*/
getopt_mode_standard = 0, /* getopt() */
getopt_mode_long, /* getopt_long() */
getopt_mode_long_only /* getopt_long_only() */
};
enum
{ /* When attempting to match a command line argument to a long form option,
* these indicate the status of the match.
*/
getopt_no_match = 0, /* no successful match */
getopt_abbreviated_match, /* argument is an abbreviation for an option */
getopt_exact_match /* argument matches the full option name */
};
int optopt = getopt_unknown; /* return value for option being evaluated */
/* Some BSD applications expect to be able to reinitialise `getopt' parsing
* by setting a global variable called `optreset'. We provide an obfuscated
* API, which allows applications to emulate this brain damage; however, any
* use of this is non-portable, and is strongly discouraged.
*/
#define optreset __mingw_optreset
int optreset = 0;
static
int getopt_missing_arg( const CHAR *optstring )
{
/* Helper function to determine the appropriate return value,
* for the case where a required option argument is missing.
*/
if( (*optstring == getopt_pluschar) || (*optstring == getopt_switchar) )
++optstring;
return (*optstring == getopt_takes_argument)
? getopt_takes_argument
: getopt_unknown;
}
/* `complain' macro facilitates the generation of simple built-in
* error messages, displayed on various fault conditions, provided
* `opterr' is non-zero.
*/
#define complain( MSG, ARG ) if( opterr ) \
fprintf( stderr, "%s: "MSG"\n", PROGNAME, ARG )
static
int getopt_argerror( int mode, char *fmt, CHAR *prog, struct option *opt, int retval )
{
/* Helper function, to generate more complex built-in error
* messages, for invalid arguments to long form options ...
*/
if( opterr )
{
/* ... but, displayed only if `opterr' is non-zero.
*/
char flag[] = "--";
if( mode != getopt_mode_long )
/*
* only display one hyphen, for implicit long form options,
* improperly resolved by `getopt_long_only()'.
*/
flag[1] = 0;
/*
* always preface the program name ...
*/
fprintf( stderr, "%s: ", prog );
/*
* to the appropriate, option specific message.
*/
fprintf( stderr, fmt, flag, opt->name );
}
/* Whether displaying the message, or not, always set `optopt'
* to identify the faulty option ...
*/
optopt = opt->val;
/*
* and return the `invalid option' indicator.
*/
return retval;
}
/* `getopt_conventions' establish behavioural options, to control
* the operation of `getopt_parse()', e.g. to select between POSIX
* and GNU style argument parsing behaviour.
*/
#define getopt_set_conventions 0x1000
#define getopt_posixly_correct 0x0010
static
int getopt_conventions( int flags )
{
static int conventions = 0;
if( (conventions == 0) && ((flags & getopt_set_conventions) == 0) )
{
/* default conventions have not yet been established;
* initialise them now!
*/
conventions = getopt_set_conventions;
if( flags == getopt_pluschar )
conventions |= getopt_posixly_correct;
}
else if( flags & getopt_set_conventions )
/*
* default conventions may have already been established,
* but this is a specific request to augment them.
*/
conventions |= flags;
/* in any event, return the currently established conventions.
*/
return conventions;
}
static
int is_switchar( CHAR flag )
{
/* A simple helper function, used to identify the switch character
* introducing an optional command line argument.
*/
return flag == getopt_switchar;
}
static
const CHAR *getopt_match( CHAR lookup, const CHAR *opt_string )
{
/* Helper function, used to identify short form options.
*/
if( (*opt_string == getopt_pluschar) || (*opt_string == getopt_switchar) )
++opt_string;
if( *opt_string == getopt_takes_argument )
++opt_string;
do if( lookup == *opt_string ) return opt_string;
while( *++opt_string );
return NULL;
}
static
int getopt_match_long( const CHAR *nextchar, const CHAR *optname )
{
/* Helper function, used to identify potential matches for
* long form options.
*/
CHAR matchchar;
while( (matchchar = *nextchar++) && (matchchar == *optname) )
/*
* skip over initial substring which DOES match.
*/
++optname;
if( matchchar )
{
/* did NOT match the entire argument to an initial substring
* of a defined option name ...
*/
if( matchchar != getopt_arg_assign )
/*
* ... and didn't stop at an `=' internal field separator,
* so this is NOT a possible match.
*/
return getopt_no_match;
/* DID stop at an `=' internal field separator,
* so this IS a possible match, and what follows is an
* argument to the possibly matched option.
*/
optarg = (char *)(nextchar);
}
return *optname
/*
* if we DIDN'T match the ENTIRE text of the option name,
* then it's a possible abbreviated match ...
*/
? getopt_abbreviated_match
/*
* but if we DID match the entire option name,
* then it's a DEFINITE EXACT match.
*/
: getopt_exact_match;
}
static
int getopt_resolved( int mode, int argc, CHAR *const *argv, int *argind,
struct option *opt, int index, int *retindex, const CHAR *optstring )
{
/* Helper function to establish appropriate return conditions,
* on resolution of a long form option.
*/
if( retindex != NULL )
*retindex = index;
/* On return, `optind' should normally refer to the argument, if any,
* which follows the current one; it is convenient to set this, before
* checking for the presence of any `optarg'.
*/
optind = *argind + 1;
if( optarg && (opt[index].has_arg == no_argument) )
/*
* it is an error for the user to specify an option specific argument
* with an option which doesn't expect one!
*/
return getopt_argerror( mode, "option `%s%s' doesn't accept an argument\n",
PROGNAME, opt + index, getopt_unknown );
else if( (optarg == NULL) && (opt[index].has_arg == required_argument) )
{
/* similarly, it is an error if no argument is specified
* with an option which requires one ...
*/
if( optind < argc )
/*
* ... except that the requirement may be satisfied from
* the following command line argument, if any ...
*/
optarg = argv[*argind = optind++];
else
/* so fail this case, only if no such argument exists!
*/
return getopt_argerror( mode, "option `%s%s' requires an argument\n",
PROGNAME, opt + index, getopt_missing_arg( optstring ) );
}
/* when the caller has provided a return buffer ...
*/
if( opt[index].flag != NULL )
{
/* ... then we place the proper return value there,
* and return a status code of zero ...
*/
*(opt[index].flag) = opt[index].val;
return 0;
}
/* ... otherwise, the return value becomes the status code.
*/
return opt[index].val;
}
static
int getopt_verify( const CHAR *nextchar, const CHAR *optstring )
{
/* Helper function, called by getopt_parse() when invoked
* by getopt_long_only(), to verify when an unmatched or an
* ambiguously matched long form option string is valid as
* a short form option specification.
*/
if( ! (nextchar && *nextchar && optstring && *optstring) )
/*
* There are no characters to be matched, or there are no
* valid short form option characters to which they can be
* matched, so this can never be valid.
*/
return 0;
while( *nextchar )
{
/* For each command line character in turn ...
*/
const CHAR *test;
if( (test = getopt_match( *nextchar++, optstring )) == NULL )
/*
* ... there is no short form option to match the current
* candidate, so the entire argument fails.
*/
return 0;
if( test[1] == getopt_takes_argument )
/*
* The current candidate is valid, and it matches an option
* which takes an argument, so this command line argument is
* a valid short form option specification; accept it.
*/
return 1;
}
/* If we get to here, then every character in the command line
* argument was valid as a short form option; accept it.
*/
return 1;
}
static
#define getopt_std_args int argc, CHAR *const argv[], const CHAR *optstring
int getopt_parse( int mode, getopt_std_args, ... )
{
/* Common core implementation for ALL `getopt' functions.
*/
static int argind = 0;
static int optbase = 0;
static const CHAR *nextchar = NULL;
static int optmark = 0;
if( (optreset |= (optind < 1)) || (optind < optbase) )
{
/* POSIX does not prescribe any definitive mechanism for restarting
* a `getopt' scan, but some applications may require such capability.
* We will support it, by allowing the caller to adjust the value of
* `optind' downwards, (nominally setting it to zero). Since POSIX
* wants `optind' to have an initial value of one, but we want all
* of our internal place holders to be initialised to zero, when we
* are called for the first time, we will handle such a reset by
* adjusting all of the internal place holders to one less than
* the adjusted `optind' value, (but never to less than zero).
*/
if( optreset )
{
/* User has explicitly requested reinitialisation...
* We need to reset `optind' to it's normal initial value of 1,
* to avoid a potential infinitely recursive loop; by doing this
* up front, we also ensure that the remaining place holders
* will be correctly reinitialised to no less than zero.
*/
optind = 1;
/* We also need to clear the `optreset' request...
*/
optreset = 0;
}
/* Now, we may safely reinitialise the internal place holders, to
* one less than `optind', without fear of making them negative.
*/
optmark = optbase = argind = optind - 1;
nextchar = NULL;
}
/* From a POSIX perspective, the following is `undefined behaviour';
* we implement it thus, for compatibility with GNU and BSD getopt.
*/
else if( optind > (argind + 1) )
{
/* Some applications expect to be able to manipulate `optind',
* causing `getopt' to skip over one or more elements of `argv';
* POSIX doesn't require us to support this brain-damaged concept;
* (indeed, POSIX defines no particular behaviour, in the event of
* such usage, so it must be considered a bug for an application
* to rely on any particular outcome); nonetheless, Mac-OS-X and
* BSD actually provide *documented* support for this capability,
* so we ensure that our internal place holders keep track of
* external `optind' increments; (`argind' must lag by one).
*/
argind = optind - 1;
/* When `optind' is misused, in this fashion, we also abandon any
* residual text in the argument we had been parsing; this is done
* without any further processing of such abandoned text, assuming
* that the caller is equipped to handle it appropriately.
*/
nextchar = NULL;
}
if( nextchar && *nextchar )
{
/* we are parsing a standard, or short format, option argument ...
*/
const CHAR *optchar;
if( (optchar = getopt_match( optopt = *nextchar++, optstring )) != NULL )
{
/* we have identified it as valid ...
*/
if( optchar[1] == getopt_takes_argument )
{
/* and determined that it requires an associated argument ...
*/
if( ! *(optarg = (char *)(nextchar)) )
{
/* the argument is NOT attached ...
*/
if( optchar[2] == getopt_takes_argument )
/*
* but this GNU extension marks it as optional,
* so we don't provide one on this occasion.
*/
optarg = NULL;
/* otherwise this option takes a mandatory argument,
* so, provided there is one available ...
*/
else if( (argc - argind) > 1 )
/*
* we take the following command line argument,
* as the appropriate option argument.
*/
optarg = argv[++argind];
/* but if no further argument is available,
* then there is nothing we can do, except for
* issuing the requisite diagnostic message.
*/
else
{
complain( "option requires an argument -- %c", optopt );
return getopt_missing_arg( optstring );
}
}
optind = argind + 1;
nextchar = NULL;
}
else
optarg = NULL;
optind = (nextchar && *nextchar) ? argind : argind + 1;
return optopt;
}
/* if we didn't find a valid match for the specified option character,
* then we fall through to here, so take appropriate diagnostic action.
*/
if( mode == getopt_mode_long_only )
{
complain( "unrecognised option `-%s'", --nextchar );
nextchar = NULL;
optopt = 0;
}
else
complain( "invalid option -- %c", optopt );
optind = (nextchar && *nextchar) ? argind : argind + 1;
return getopt_unknown;
}
if( optmark > optbase )
{
/* This can happen, in GNU parsing mode ONLY, when we have
* skipped over non-option arguments, and found a subsequent
* option argument; in this case we permute the arguments.
*/
int index;
/*
* `optspan' specifies the number of contiguous arguments
* which are spanned by the current option, and so must be
* moved together during permutation.
*/
const int optspan = argind - optmark + 1;
/*
* we use `this_arg' to store these temporarily.
*/
CHAR **this_arg = malloc(sizeof(CHAR*) * optspan);
/*
* we cannot manipulate `argv' directly, since the `getopt'
* API prototypes it as `read-only'; this cast to `arglist'
* allows us to work around that restriction.
*/
CHAR **arglist = (char **)(argv);
/* save temporary copies of the arguments which are associated
* with the current option ...
*/
for( index = 0; index < optspan; ++index )
this_arg[index] = arglist[optmark + index];
/* move all preceding non-option arguments to the right,
* overwriting these saved arguments, while making space
* to replace them in their permuted location.
*/
for( --optmark; optmark >= optbase; --optmark )
arglist[optmark + optspan] = arglist[optmark];
/* restore the temporarily saved option arguments to
* their permuted location.
*/
for( index = 0; index < optspan; ++index )
arglist[optbase + index] = this_arg[index];
/* adjust `optbase', to account for the relocated option.
*/
optbase += optspan;
free(this_arg);
}
else
/* no permutation occurred ...
* simply adjust `optbase' for all options parsed so far.
*/
optbase = argind + 1;
/* enter main parsing loop ...
*/
while( argc > ++argind )
{
/* inspect each argument in turn, identifying possible options ...
*/
if( is_switchar( *(nextchar = argv[optmark = argind]) ) && *++nextchar )
{
/* we've found a candidate option argument ... */
if( is_switchar( *nextchar ) )
{
/* it's a double hyphen argument ... */
const CHAR *refchar = nextchar;
if( *++refchar )
{
/* and it looks like a long format option ...
* `getopt_long' mode must be active to accept it as such,
* `getopt_long_only' also qualifies, but we must downgrade
* it to force explicit handling as a long format option.
*/
if( mode >= getopt_mode_long )
{
nextchar = refchar;
mode = getopt_mode_long;
}
}
else
{
/* this is an explicit `--' end of options marker, so wrap up now!
*/
if( optmark > optbase )
{
/* permuting the argument list as necessary ...
* (note use of `this_arg' and `arglist', as above).
*/
CHAR *this_arg = argv[optmark];
CHAR **arglist = (CHAR **)(argv);
/* move all preceding non-option arguments to the right ...
*/
do arglist[optmark] = arglist[optmark - 1];
while( optmark-- > optbase );
/* reinstate the `--' marker, in its permuted location.
*/
arglist[optbase] = this_arg;
}
/* ... before finally bumping `optbase' past the `--' marker,
* and returning the `all done' completion indicator.
*/
optind = ++optbase;
return getopt_all_done;
}
}
else if( mode < getopt_mode_long_only )
{
/* it's not an explicit long option, and `getopt_long_only' isn't active,
* so we must explicitly try to match it as a short option.
*/
mode = getopt_mode_standard;
}
if( mode >= getopt_mode_long )
{
/* the current argument is a long form option, (either explicitly,
* introduced by a double hyphen, or implicitly because we were called
* by `getopt_long_only'); this is where we parse it.
*/
int lookup;
int matched = -1;
/* we need to fetch the `extra' function arguments, which are
* specified for the `getopt_long' APIs.
*/
va_list refptr;
struct option *longopts;
int *optindex;
va_start( refptr, optstring );
longopts = va_arg( refptr, struct option * );
optindex = va_arg( refptr, int * );
va_end( refptr );
/* ensuring that `optarg' does not inherit any junk, from parsing
* preceding arguments ...
*/
optarg = NULL;
for( lookup = 0; longopts && longopts[lookup].name; ++lookup )
{
/* scan the list of defined long form options ...
*/
switch( getopt_match_long( nextchar, longopts[lookup].name ) )
{
/* looking for possible matches for the current argument.
*/
case getopt_exact_match:
/*
* when an exact match is found,
* return it immediately, setting `nextchar' to NULL,
* to ensure we don't mistakenly try to match any
* subsequent characters as short form options.
*/
nextchar = NULL;
return getopt_resolved( mode, argc, argv, &argind,
longopts, lookup, optindex, optstring );
case getopt_abbreviated_match:
/*
* but, for a partial (initial substring) match ...
*/
if( matched >= 0 )
{
/* if this is not the first, then we have an ambiguity ...
*/
if( (mode == getopt_mode_long_only)
/*
* However, in the case of getopt_long_only(), if
* the entire ambiguously matched string represents
* a valid short option specification, then we may
* proceed to interpret it as such.
*/
&& getopt_verify( nextchar, optstring ) )
return getopt_parse( mode, argc, argv, optstring );
/* If we get to here, then the ambiguously matched
* partial long option isn't valid for short option
* evaluation; reset parser context to resume with
* the following command line argument, diagnose
* ambiguity, and bail out.
*/
optopt = 0;
nextchar = NULL;
optind = argind + 1;
complain( "option `%s' is ambiguous", argv[argind] );
return getopt_unknown;
}
/* otherwise just note that we've found a possible match ...
*/
matched = lookup;
}
}
if( matched >= 0 )
{
/* if we get to here, then we found exactly one partial match,
* so return it, as for an exact match.
*/
nextchar = NULL;
return getopt_resolved( mode, argc, argv, &argind,
longopts, matched, optindex, optstring );
}
/* if here, then we had what SHOULD have been a long form option,
* but it is unmatched ...
*/
if( (mode < getopt_mode_long_only)
/*
* ... although paradoxically, `mode == getopt_mode_long_only'
* allows us to still try to match it as a short form option.
*/
|| (getopt_verify( nextchar, optstring ) == 0) )
{
/* When it cannot be matched, reset the parsing context to
* resume from the next argument, diagnose the failed match,
* and bail out.
*/
optopt = 0;
nextchar = NULL;
optind = argind + 1;
complain( "unrecognised option `%s'", argv[argind] );
return getopt_unknown;
}
}
/* fall through to handle standard short form options...
* when the option argument format is neither explictly identified
* as long, nor implicitly matched as such, and the argument isn't
* just a bare hyphen, (which isn't an option), then we make one
* recursive call to explicitly interpret it as short format.
*/
if( *nextchar )
return getopt_parse( mode, argc, argv, optstring );
}
/* if we get to here, then we've parsed a non-option argument ...
* in GNU compatibility mode, we step over it, so we can permute
* any subsequent option arguments, but ...
*/
if( *optstring == getopt_switchar )
{
/* if `optstring' begins with a `-' character, this special
* GNU specific behaviour requires us to return the non-option
* arguments in strict order, as pseudo-arguments to a special
* option, with return value defined as `getopt_ordered'.
*/
nextchar = NULL;
optind = argind + 1;
optarg = argv[argind];
return getopt_ordered;
}
if( getopt_conventions( *optstring ) & getopt_posixly_correct )
/*
* otherwise ...
* for POSIXLY_CORRECT behaviour, or if `optstring' begins with
* a `+' character, then we break out of the parsing loop, so that
* the scan ends at the current argument, with no permutation.
*/
break;
}
/* fall through when all arguments have been evaluated,
*/
optind = optbase;
return getopt_all_done;
}
/* All three public API entry points are trivially defined,
* in terms of the internal `getopt_parse' function.
*/
int getopt( getopt_std_args )
{
return getopt_parse( getopt_mode_standard, argc, argv, optstring );
}
int getopt_long( getopt_std_args, const struct option *opts, int *index )
{
return getopt_parse( getopt_mode_long, argc, argv, optstring, opts, index );
}
int getopt_long_only( getopt_std_args, const struct option *opts, int *index )
{
return getopt_parse( getopt_mode_long_only, argc, argv, optstring, opts, index );
}
#ifdef __weak_alias
/*
* These Microsnot style uglified aliases are provided for compatibility
* with the previous MinGW implementation of the getopt API.
*/
__weak_alias( getopt, _getopt )
__weak_alias( getopt_long, _getopt_long )
__weak_alias( getopt_long_only, _getopt_long_only )
#endif
#ifdef __cplusplus
}
#endif
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */