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
Treehugger Robot
ed91226cec Merge "Remove redundant register storage class specifiers" 2016-10-28 01:08:50 +00:00
Martin Storsjo
6ec082c6c3 Remove redundant register storage class specifiers
Clang warns about this being deprecated, when building without specifying
-std=c++98.

This doesn't give any measurable encoding speed impact on ARM or AArch64,
on neither GCC nor Clang.

Change-Id: I63a0bbd1dccb97547522da188ee585d4d8127c29
2016-10-18 09:22:55 +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
Treehugger Robot
4556cb9cb8 Merge "Add casts to avoid errors due to narrowing" 2016-10-18 03:05:51 +00:00
Martin Storsjo
6d7d5013ea Add casts to avoid errors due to narrowing
This fixes building in C++11 mode, which normally errors out
on narrowing hex literals to signed long.

This is similar to what was done in git commit ef30836651
(change id I64d19a8a8059c5a96386b1eaac297fd2469515f8), completing
the fix for that category of issues.

Change-Id: I1907bc947d43bf44910fb2b34bf2b31c0e53aa53
2016-10-17 10:32:24 +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
Jean-Michel Trivi
f935254cc9 Merge "Avoid a warning about extra parentheses" 2016-09-09 22:06:10 +00:00
Martin Storsjo
ebb66ffd4a Avoid a warning about extra parentheses
This fixes the following warning:

libSBRenc/src/sbr_encoder.cpp:1942:14: warning: equality comparison
      with extraneous parentheses [-Wparentheses-equality]

Change-Id: I2c833d19348574473c752076a4efff6642c0d653
2016-08-30 09:57:04 +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
d52f374768.

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
Glenn Kasten
00fc1c66d5 Merge "Disable warnings that are not easily fixable" am: 8192b1a
am: 2a923c9

* commit '2a923c92869efb277ca7d67ab6c27617ec26c128':
  Disable warnings that are not easily fixable

Change-Id: I920b16bdaa1ce7a00c91e129b950f0d486a1fa37
2016-04-20 23:40:45 +00:00
Glenn Kasten
c3f7cf7f1b Merge "Add default case for undefined pointer initialization" am: 9d0179c
am: 27625f2

* commit '27625f27066421ce38250272f4bb751cf6f58c17':
  Add default case for undefined pointer initialization

Change-Id: I601dc2afdfa8db2008628e05068d277a617c022d
2016-04-20 23:40:45 +00:00
Glenn Kasten
e34e2b9d54 Merge "Left shift of negative int is undefined" am: 6ae5480
am: 2b2e97b

* commit '2b2e97b893b16b69c7728d16e8653b9c94944294':
  Left shift of negative int is undefined

Change-Id: Ie90b850b7adf787dfb47f8b7c43a22744c3a7fa0
2016-04-20 23:40:45 +00:00
Glenn Kasten
28099687b7 resolve merge conflicts of ad1e898 to nyc-dev-plus-aosp
Change-Id: If143807a233d47fb7fd269fd263a8a898109b060
2016-04-20 16:28:31 -07:00
Glenn Kasten
2a923c9286 Merge "Disable warnings that are not easily fixable"
am: 8192b1a

* commit '8192b1a98f60cc39253c658ba1ca70a70c2e0dfa':
  Disable warnings that are not easily fixable

Change-Id: I5dc1fabd29cfb7024f8362359a796efd1764032d
2016-04-20 19:00:07 +00:00
Glenn Kasten
27625f2706 Merge "Add default case for undefined pointer initialization"
am: 9d0179c

* commit '9d0179c8a85f2b50bafdf6715fc266bc92771756':
  Add default case for undefined pointer initialization

Change-Id: I311521adebb1949747f0cb34bee19a57d8199558
2016-04-20 19:00:06 +00:00
Glenn Kasten
2b2e97b893 Merge "Left shift of negative int is undefined"
am: 6ae5480

* commit '6ae54806ab88efd76e884447680fd30b340936fd':
  Left shift of negative int is undefined

Change-Id: If6a4abe686d3ab6b7f825058255b03aa46055484
2016-04-20 19:00:06 +00:00
Glenn Kasten
ad1e8985d9 Merge "Remove redundant parentheses around == comparison operator"
am: 34fb053

* commit '34fb05353bbabe1ba04362f26b3ae507fbb687d4':
  Remove redundant parentheses around == comparison operator

Change-Id: I7a37ef8293371cc0287a0e0b9f0115f82f294b31
2016-04-20 19:00:06 +00:00
Glenn Kasten
8192b1a98f Merge "Disable warnings that are not easily fixable" 2016-04-20 18:45:30 +00:00
Glenn Kasten
9d0179c8a8 Merge "Add default case for undefined pointer initialization" 2016-04-20 18:45:18 +00:00
Glenn Kasten
6ae54806ab Merge "Left shift of negative int is undefined" 2016-04-20 18:45:09 +00:00
Glenn Kasten
34fb05353b Merge "Remove redundant parentheses around == comparison operator" 2016-04-20 18:44:59 +00:00
Jean-Michel Trivi
be845a7fc2 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9 am: 0a20959871 am: 6318d60241 am: 7147e71a75 am: 1de50b286f am: d110691d01 am: 0cf3a7671a
am: 9d4702f2d9

* commit '9d4702f2d9ecec00c4e28de638b1f79afb5d696c':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I0a57275a4ebc04cc3acafc6a0325b7fefe8e5ef0
2016-04-19 01:34:40 +00:00
Jean-Michel Trivi
9d4702f2d9 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9 am: 0a20959871 am: 6318d60241 am: 7147e71a75 am: 1de50b286f am: d110691d01
am: 0cf3a7671a

* commit '0cf3a7671ad40c1036387d55462f1710a44eec31':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I7ca67acba7d69472865efa84a63a49c7768487c5
2016-04-19 01:32:26 +00:00
Jean-Michel Trivi
0cf3a7671a Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9 am: 0a20959871 am: 6318d60241 am: 7147e71a75 am: 1de50b286f
am: d110691d01

* commit 'd110691d01e15a555d84fcd98e4b275dd38b37ba':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I6c009e94d626cc1dd6ec1510fd2e07c1b3a4031a
2016-04-19 01:30:15 +00:00
Jean-Michel Trivi
d110691d01 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9 am: 0a20959871 am: 6318d60241 am: 7147e71a75
am: 1de50b286f

* commit '1de50b286fdadc07f94e0d8fae69a564796ab12a':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: Ib1dce026d6ddc9fdfa68cc5b4213a2685dc1ac17
2016-04-19 01:27:53 +00:00
Jean-Michel Trivi
1de50b286f Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9 am: 0a20959871 am: 6318d60241
am: 7147e71a75

* commit '7147e71a75a48009e6d2b835422767cf466813d8':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I7f677fae038640739834d4c44309680b78748acf
2016-04-19 01:25:09 +00:00
Jean-Michel Trivi
7147e71a75 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9 am: 0a20959871
am: 6318d60241

* commit '6318d6024194f89d809f4e22266105f27389f41b':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I1a836bd8b024948f18b2d2c0e912601722f887bc
2016-04-19 01:00:01 +00:00
Jean-Michel Trivi
6318d60241 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638 am: 78653b30e9
am: 0a20959871

* commit '0a209598713cccc4f10e9c0036df487bea5af312':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: If2339aad0e0e825302773f2f04f0dd43cc754ac6
2016-04-19 00:57:44 +00:00
Jean-Michel Trivi
0a20959871 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f am: 1a54e8f638
am: 78653b30e9

* commit '78653b30e9c1907d4c6eefa30ff954e0c4398447':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I53cabb3bab17e8754a03648ffac356e4a3a05e28
2016-04-19 00:55:30 +00:00
Jean-Michel Trivi
78653b30e9 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425 am: b762ff3e4f
am: 1a54e8f638

* commit '1a54e8f6385f9cbb8d950f0ff003bb71daa62caf':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I3c992ce7d3a60685f75a944d8d588fb9ff0d050c
2016-04-19 00:53:17 +00:00
Jean-Michel Trivi
1a54e8f638 Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d am: be3ff35425
am: b762ff3e4f

* commit 'b762ff3e4fdc29ce517824e19d187ba667e80623':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I29eaf51574e1834f223a9755a353abd90fcf912b
2016-04-19 00:50:57 +00:00
Jean-Michel Trivi
b762ff3e4f Fix aacDecoder_drcExtractAndMap() am: 97a1b8140d
am: be3ff35425

* commit 'be3ff35425f026fb3714f1bd45c40aee6737fe05':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I82060408eab9a8990c511af4c6be8a588d2a1b49
2016-04-19 00:48:42 +00:00
Jean-Michel Trivi
be3ff35425 Fix aacDecoder_drcExtractAndMap()
am: 97a1b8140d

* commit '97a1b8140d410ed3942006aa22b40ccb322f747b':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I1bf523e635139d71ef124462bd61e0da06191d35
2016-04-19 00:46:26 +00:00
Glenn Kasten
32db3a45df Disable warnings that are not easily fixable
Bug: 28026175
Change-Id: I6e9cfcd9efeb853caee01b54b241f24e64cf1e94
2016-04-18 16:11:27 -07:00
Glenn Kasten
1dd7649666 Add default case for undefined pointer initialization
Bug: 28026175
Change-Id: I1b149bf1573296df18abbe44f737bd87ab3913f9
2016-04-18 16:11:16 -07:00
Glenn Kasten
4bd4510b19 Left shift of negative int is undefined
Bug: 28026175
Change-Id: I9dc851b818262e95711033bdc03b7b7f30cff133
2016-04-18 16:11:01 -07:00
Glenn Kasten
76b428d4b4 Remove redundant parentheses around == comparison operator
Bug: 28026175
Change-Id: I8ff9d8d1dd73933dc181f2745292a0a3398a2479
2016-04-18 16:10:57 -07:00
Jean-Michel Trivi
97a1b8140d Fix aacDecoder_drcExtractAndMap()
Parse DVB DRC data only when numThreads is below
 MAX_DRC_THREADS. The post-increment is necessary as
 it is used in fill element DRC data section.
This solution parses as many DRC payloads as allowed by
 MAX_DRC_THREADS and skips all remaining DRC elements in the stream.

Bug 27792766
Bug 26751339

Change-Id: Ie1641888bac1757c4d1491119f977fc5d436eaea
2016-04-15 08:14:50 -07:00
Jean-Michel Trivi
3fbcee8020 AAC/SBR decoder improvements and bugfixes
am: 203e3f2

* commit '203e3f28fbebec7011342017fafc2a0bda0ce530':
  AAC/SBR decoder improvements and bugfixes

Change-Id: I2f7f5bb7f4c486347a1fdbd7c481cde33037441e
2016-04-09 00:36:07 +00:00
Jean-Michel Trivi
125815b0ed AAC/SBR encoder improvements
am: 46ba367

* commit '46ba3676b854acbc69a4c7845f578d4c2886377b':
  AAC/SBR encoder improvements

Change-Id: Id839c5ba8b79eddb7e239b7ec1b26fb5079b7d81
2016-04-09 00:36:07 +00:00
Jean-Michel Trivi
203e3f28fb AAC/SBR decoder improvements and bugfixes
* AAC-Decoder

   - Add support for AOT 20 (ER-AAC scalable) (base layer only)
   - Add support for AAC as used in Digital Radio Mondiale (DRM30/DRM+)
     Modified file(s):
        libAACdec/src/aacdecoder.cpp
        libAACdec/src/aacdecoder_lib.cpp
        libFDK/src/FDK_core.cpp
        libFDK/src/FDK_tools_rom.cpp
        libMpegTPDec/src/tpdec_asc.cpp
        libMpegTPDec/src/tpdec_lib.cpp
        libMpegTPDec/src/version
        libSBRdec/include/sbrdecoder.h
        libSBRdec/src/env_extr.h
        libSBRdec/src/sbrdecoder.cpp
     Added file(s):
        libMpegTPDec/src/tpdec_drm.cpp
        libMpegTPDec/src/tpdec_drm.h

   - Fix sanity check in HCR module that was performed at the wrong point in time.
     Modified file(s):
        libAACdec/src/aacdecoder_lib.cpp
        libAACdec/src/block.cpp

   - Extend core sampling rate support up to 96 kHz.
     Modified file(s):
        libAACdec/src/aac_rom.cpp
        libAACdec/src/aacdecoder.cpp
        libAACdec/src/aacdecoder_lib.cpp

   - Return correct audio output channel description according number of output
     channels.
     Modified file(s):
        libAACdec/src/aacdecoder_lib.cpp

   - Indroduce decoder intern output buffer. This change allows to use framework
     output buffer with the actual size of the deocder output channels.
     Modified file(s):
        libAACdec/include/aacdecoder_lib.h
        libAACdec/src/aacdecoder.h
        libAACdec/src/aacdecoder_lib.cpp

* SBR-Decoder

   - Increase robustness for erroneous input data.
   - Improve error concealment performance.
   - Fix handling of lowest sub-band for LD-SBR
     Modified file(s):
        libAACdec/src/aacdecoder.cpp
        libAACdec/src/aacdecoder_lib.cpp
        libSBRdec/src/env_calc.cpp
        libSBRdec/src/env_dec.cpp
        libSBRdec/src/env_extr.cpp
        libSBRdec/src/env_extr.h
        libSBRdec/src/sbr_dec.cpp
        libSBRdec/src/sbr_rom.cpp
        libSBRdec/src/sbr_rom.h
        libSBRdec/src/sbrdecoder.cpp

   - Add QMF delay compensation for ELD v2 streams decoded with the complex
     low delay filter-bank.
     Modified file(s):
        libSBRdec/src/sbr_dec.cpp
        libSBRdec/src/sbr_dec.h
        libSBRdec/src/sbrdecoder.cpp

   - Introduce a different handling of frames to be flushed
     dependent on whether there are delayed frames available or not.
     Modified file(s):
        libSBRdec/src/sbr_ram.h
        libSBRdec/src/sbrdecoder.cpp

   - Calculate the correct number of samples for dual-mono copy in case of no
     available PS data.
     Modified file(s):
        libSBRdec/src/sbrdecoder.cpp

* SYS-Library

   - Change include order of genericStds.h to prevent conflict with definitions
     which are also used in math.h.
     Modified file(s):
        libSYS/src/genericStds.cpp

Change-Id: I3ecffbad85f39b056213107955cfadbeb3f4b6e1
2016-04-08 19:10:30 +00:00
Jean-Michel Trivi
46ba3676b8 AAC/SBR encoder improvements
* AAC-Encoder

  - AAC-ELD core encoder audio quality tuning. Update tuning tables, configure
    bitreservoir size and adapt afterburner iteration value.
     Modified file(s):
        libAACenc/src/aacenc.h
        libAACenc/src/aacenc_lib.cpp
        libAACenc/src/adj_thr.cpp
        libAACenc/src/adj_thr.h
        libAACenc/src/adj_thr_data.h
        libAACenc/src/bandwidth.cpp
        libAACenc/src/pnsparam.cpp
        libAACenc/src/qc_main.cpp

   - Introduze dead zone quantizer for ELD to improve audio quality at certain
     configurations.
     Modified file(s):
        libAACenc/src/aacenc_lib.cpp
        libAACenc/src/adj_thr.cpp
        libAACenc/src/adj_thr.h
        libAACenc/src/qc_data.h
        libAACenc/src/qc_main.cpp
        libAACenc/src/quantize.cpp
        libAACenc/src/quantize.h
        libAACenc/src/sf_estim.cpp
        libAACenc/src/sf_estim.h

   - Revise TNS module to improve ELD audio quality.
   - Use new window function and separate prediction gain according TNS filters.
   - Add missing memory initilization to TNS configuration.
     Modified file(s):
        libAACenc/src/aacenc_lib.cpp
        libAACenc/src/aacenc_tns.cpp
        libAACenc/src/aacenc_tns.h
        libAACenc/src/psy_main.cpp
        libAACenc/src/tns_func.h

* SBR-Encoder

   - Revise frequency resolution calculation and handle differently depending
     on number of envelopes and split frames decision.
   - Add and adjust ELD SBR tuning tables.
     Modified file(s):
        libSBRenc/include/sbr_encoder.h
        libSBRenc/src/bit_sbr.h
        libSBRenc/src/env_est.cpp
        libSBRenc/src/fram_gen.cpp
        libSBRenc/src/fram_gen.h
        libSBRenc/src/mh_det.cpp
        libSBRenc/src/sbr_def.h
        libSBRenc/src/sbr_encoder.cpp
        libSBRenc/src/sbr_rom.cpp
        libSBRenc/src/tran_det.cpp

   - Replace ELD transient detector with fast implementation.
     Modified file(s):
        libSBRenc/src/env_est.cpp
        libSBRenc/src/env_est.h
        libSBRenc/src/fram_gen.cpp
        libSBRenc/src/sbr_def.h
        libSBRenc/src/sbr_encoder.cpp
        libSBRenc/src/tran_det.cpp
        libSBRenc/src/tran_det.h

* FDK-Library
   - Introduce generic compare function in tools library.
     Modified file(s):
        libFDK/include/fixpoint_math.h
        libFDK/src/FDK_core.cpp

* SBR-Encoder

  -  Revise ELD frame splitter to improve bit distribution.
     Modified file(s):
        libSBRenc/include/sbr_encoder.h
        libSBRenc/src/bit_sbr.h
        libSBRenc/src/env_est.cpp
        libSBRenc/src/fram_gen.cpp
        libSBRenc/src/fram_gen.h
        libSBRenc/src/sbr_encoder.cpp
        libSBRenc/src/tran_det.cpp
        libSBRenc/src/tran_det.h

   - Configure amplitude resolution according the tonality of the audio signal.
     Modified file(s):
        libSBRenc/include/sbr_encoder.h
        libSBRenc/src/bit_sbr.h
        libSBRenc/src/env_est.cpp
        libSBRenc/src/nf_est.cpp
        libSBRenc/src/nf_est.h
        libSBRenc/src/sbr_def.h
        libSBRenc/src/sbr_encoder.cpp
        libSBRenc/src/ton_corr.cpp
        libSBRenc/src/ton_corr.h
        libSBRenc/src/tran_det.cpp
        libSBRenc/src/tran_det.h

Change-Id: Ie0672b989a06ee63b50240616b8d1d4b790b6cb2
2016-04-08 10:52:42 -07:00
Jean-Michel Trivi
d75233c2da Fix aacDecoder_drcExtractAndMap()
am: 4834f01

* commit '4834f01bdf9b9f371fcbb0b9cf4f7297fdf1fd55':
  Fix aacDecoder_drcExtractAndMap()

Change-Id: I4f9994a4d4e858b6193b006d6971536c391e0478
2016-04-05 21:08:27 +00:00
Jean-Michel Trivi
4834f01bdf Fix aacDecoder_drcExtractAndMap()
Parse DVB DRC data only when numThreads is below
 MAX_DRC_THREADS. The post-increment is necessary as
 it is used in fill element DRC data section.
This solution parses as many DRC payloads as allowed by
 MAX_DRC_THREADS and skips all remaining DRC elements in the stream.

Bug 27792766
Bug 26751339

Change-Id: Ie1641888bac1757c4d1491119f977fc5d436eaea
2016-04-05 20:50:05 +00:00
Jean-Michel Trivi
65750eae65 SBR/AAC encoder updates, code clean up
am: e1c78ed

* commit 'e1c78ed73faa51f2c7fcb0c4a17a92be9cc747f5':
  SBR/AAC encoder updates, code clean up

Change-Id: I908adc47823de593c3e258c67f360da9321780f5
2016-04-05 17:43:33 +00:00
Jean-Michel Trivi
0713b4acff Remove compiler warnings, revised ARM QMF encoder
am: ef30836

* commit 'ef30836651bf059c3120c03dd11e08b6aafdae13':
  Remove compiler warnings, revised ARM QMF encoder

Change-Id: I07babb4dc36b6ad7aebeb62c303a8380e99d691e
2016-04-05 16:11:23 +00:00
Jean-Michel Trivi
e1c78ed73f SBR/AAC encoder updates, code clean up
* SBR-Encoder

   - Prevent noise level overflow in noise floor detection.
   - Saturate threshold calculation in transient detection.
     Modified file(s):
        libSBRenc/src/nf_est.cpp
        libSBRenc/src/sbr_encoder.cpp
        libSBRenc/src/tran_det.cpp

* AAC-Encoder

   - Expand input data range of GetInvInt() function. There was an encoder
     assert observed in non-default bitrate configuration.
     Modified file(s):
        libAACenc/src/aacenc_lib.cpp
        libAACenc/src/intensity.cpp
        libFDK/include/fixpoint_math.h
        libFDK/src/FDK_core.cpp
        libFDK/src/FDK_tools_rom.cpp

   - Make sure that the encoder is stable with regard to very low audio bandwidth
     confguration parameter value.
   - Fix lowdelay blending for low audio bandwidth.
     Modified file(s):
        libAACenc/src/aacenc.cpp
        libAACenc/src/aacenc_lib.cpp
        libAACenc/src/adj_thr.cpp
        libAACenc/src/psy_configuration.cpp
        libAACenc/src/psy_main.cpp

   - Disable pseudo surround flag in case metadata matrix mixdown index is
     present in program config element.
     Modified file(s):
        libAACenc/src/aacenc_lib.cpp

   - Enable variable bitrate mode in encoder api.
   - Add AACENC_PEAK_BITRATE parameter to encoder api.
   - Add AACENC_AUDIOMUXVER parameter to encoder api.
     Modified file(s):
        libAACenc/include/aacenc_lib.h
        libAACenc/src/aacenc.cpp
        libAACenc/src/aacenc.h
        libAACenc/src/aacenc_lib.cpp
        libAACenc/src/qc_main.cpp
        libMpegTPEnc/src/tpenc_latm.cpp
        libMpegTPEnc/src/version

* FDK-Sources

   - Code clean up. Remove unneeded pseudo audio object types and transport types.
     Modified file(s):
        libAACdec/src/aacdecoder.cpp
        libAACdec/src/aacdecoder_lib.cpp
        libAACenc/include/aacenc_lib.h
        libAACenc/src/aacenc.cpp
        libAACenc/src/aacenc_lib.cpp
        libFDK/src/FDK_tools_rom.cpp
        libMpegTPDec/src/tpdec_lib.cpp
        libMpegTPDec/src/version
        libMpegTPEnc/src/tpenc_latm.cpp
        libMpegTPEnc/src/version
        libSBRdec/src/sbrdecoder.cpp
        libSBRenc/src/sbr_encoder.cpp
        libSYS/include/FDK_audio.h
        libSYS/src/genericStds.cpp

Change-Id: I807a53cb7f48c9ee7563cb8da1d0c52221576ca6
2016-04-04 17:25:36 -07:00
Jean-Michel Trivi
ef30836651 Remove compiler warnings, revised ARM QMF encoder
Bug 8493170

Change-Id: I64d19a8a8059c5a96386b1eaac297fd2469515f8
2016-04-04 15:03:26 -07:00
Jean-Michel Trivi
f86e64f5c7 Fix stack corruption happening in aacDecoder_drcExtractAndMap() am: a06d1c2 am: 47739cd am: 118fc75
am: 7657556

* commit '7657556633262752ad2db9e3914a04128bd64e1b':
  Fix stack corruption happening in aacDecoder_drcExtractAndMap()
2016-03-22 02:57:52 +00:00
Jean-Michel Trivi
7657556633 Fix stack corruption happening in aacDecoder_drcExtractAndMap() am: a06d1c2 am: 47739cd
am: 118fc75

* commit '118fc75eee6cc763a3105d6e963b77d76d114a2e':
  Fix stack corruption happening in aacDecoder_drcExtractAndMap()
2016-03-22 02:49:48 +00:00
Jean-Michel Trivi
118fc75eee Fix stack corruption happening in aacDecoder_drcExtractAndMap() am: a06d1c2
am: 47739cd

* commit '47739cd9d8d7842436b90ef14207c935b0a799fe':
  Fix stack corruption happening in aacDecoder_drcExtractAndMap()
2016-03-22 02:44:32 +00:00
Jean-Michel Trivi
47739cd9d8 Fix stack corruption happening in aacDecoder_drcExtractAndMap()
am: a06d1c2

* commit 'a06d1c2b9af1621037b48557aac42b5ecbdb03b3':
  Fix stack corruption happening in aacDecoder_drcExtractAndMap()
2016-03-22 02:36:16 +00:00
Jean-Michel Trivi
a06d1c2b9a Fix stack corruption happening in aacDecoder_drcExtractAndMap()
In the aacDecoder_drcExtractAndMap() function, self->numThreads
  can be used after having exceeded its intended max value,
  MAX_DRC_THREADS, causing memory to be cleared after the
  threadBs[MAX_DRC_THREADS] array.
The crash is prevented by never using self->numThreads with
  a value equal to or greater than MAX_DRC_THREADS.
A proper fix will be required as there seems to be an issue as
  to which entry in the threadBs array is meant to be initialized
  and used.

Bug 26751339

Change-Id: I655cc40c35d4206ab72e83b2bdb751be2fe52b5a
2016-03-21 21:59:22 +00:00
Jean-Michel Trivi
e46ff0f7f9 Fix stack corruption happening in aacDecoder_drcExtractAndMap()
In the aacDecoder_drcExtractAndMap() function, self->numThreads
  can be used after having exceeded its intended max value,
  MAX_DRC_THREADS, causing memory to be cleared after the
  threadBs[MAX_DRC_THREADS] array.
The crash is prevented by never using self->numThreads with
  a value equal to or greater than MAX_DRC_THREADS.
A proper fix will be required as there seems to be an issue as
  to which entry in the threadBs array is meant to be initialized
  and used.

Bug 26751339

Change-Id: I655cc40c35d4206ab72e83b2bdb751be2fe52b5a
2016-03-21 21:58:57 +00: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
Dan Willemsen
c203653dcb Remove __DATE__/__TIME__
am: 2d435aa433

* commit '2d435aa43323935bd8ed293f4f12cddfdee81eb3':
  Remove __DATE__/__TIME__
2015-11-03 19:44:47 +00:00
Dan Willemsen
2d435aa433 Remove __DATE__/__TIME__
Building __DATE__/__TIME__ into the binaries means that every build will
create different binaries, even if all the sources are identical. This
also means that any libraries including this one will need to be patched
during every OTA.

Nothing appears to use the build_date/build_time fields, so just replace
them with empty strings.

Bug: 24204119
Change-Id: I9543eb388a1e8ab9284df9035a62fc8942cdc082
(cherry picked from commit 6e8330732f)
2015-10-30 21:53:59 +00:00
Dan Willemsen
ca249e444b Merge "Remove __DATE__/__TIME__"
am: a73b059815

* commit 'a73b059815fc35ba689e5a8235b567b2353eabad':
  Remove __DATE__/__TIME__
2015-10-27 23:27:46 +00:00
Dan Willemsen
a73b059815 Merge "Remove __DATE__/__TIME__" 2015-10-27 23:16:31 +00:00
Dan Willemsen
6e8330732f Remove __DATE__/__TIME__
Building __DATE__/__TIME__ into the binaries means that every build will
create different binaries, even if all the sources are identical. This
also means that any libraries including this one will need to be patched
during every OTA.

Nothing appears to use the build_date/build_time fields, so just replace
them with empty strings.

Bug: 24204119
Change-Id: I9543eb388a1e8ab9284df9035a62fc8942cdc082
2015-10-23 09:48:27 -07: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
Marco Nelissen
106fb85b42 am 9f42dfb7: am b3c5a4bb: Fix crash on invalid channel config
* commit '9f42dfb7990a107da23454669459bb5e28d90726':
  Fix crash on invalid channel config
2015-09-15 02:12:36 +00:00
Marco Nelissen
9f42dfb799 am b3c5a4bb: Fix crash on invalid channel config
* commit 'b3c5a4bb8442ab3158fa1f52b790fadc64546f46':
  Fix crash on invalid channel config
2015-09-15 01:10:04 +00:00
Marco Nelissen
b3c5a4bb84 Fix crash on invalid channel config
Bug: 23876444
Change-Id: I90ad197811ebabceb5b5d74d6d3f20716fbe2d45
2015-09-08 15:50:08 +00:00
Dan Willemsen
8e8d920708 am 9f1b9bb7: (-s ours) am 5e7b21bb: Merge "build: wildcard isn\'t guaranteed to be sorted"
* commit '9f1b9bb71019b9a773d847cec6f10c198cd6c459':
2015-08-27 05:10:06 +00: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
Dan Willemsen
ba8b18e1e8 am 5e7b21bb: Merge "build: wildcard isn\'t guaranteed to be sorted"
* commit '5e7b21bb954dcf74533a1725be62cf6bffcb34ce':
  build: wildcard isn't guaranteed to be sorted
2015-08-12 00:39:30 +00:00
Dan Willemsen
9f1b9bb710 am 5e7b21bb: Merge "build: wildcard isn\'t guaranteed to be sorted"
* commit '5e7b21bb954dcf74533a1725be62cf6bffcb34ce':
  build: wildcard isn't guaranteed to be sorted
2015-08-12 00:39:04 +00:00
Dan Willemsen
5e7b21bb95 Merge "build: wildcard isn't guaranteed to be sorted" 2015-08-12 00:24:06 +00:00
Dan Willemsen
f170f89906 build: wildcard isn't guaranteed to be sorted
To prevent this from changing between builds, wrap in $(sort )

Change-Id: I0571d7d8787a40ca107c7c735d79692d27bed06e
2015-08-07 13:51:09 -07: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
Bill Yi
267940f5bd am f2df045a: Merge commit \'10d211b84a5f0790b28fcc8b3db66884d5f9c729\' into HEAD
* commit 'f2df045ae92ee655481f73b19986084308ae684c':
2015-02-20 00:22:52 +00:00
Bill Yi
f2df045ae9 Merge commit '10d211b84a5f0790b28fcc8b3db66884d5f9c729' into HEAD 2015-02-19 14:30:49 -08:00
Chih-Hung Hsieh
bd8021bef1 am 2b6bf8dc: Merge "Do not include genericStds_linux.cpp."
* commit '2b6bf8dc0941f3a4531030b950cf24fd31248b0b':
  Do not include genericStds_linux.cpp.
2015-02-18 02:53:59 +00:00
Chih-Hung Hsieh
2b6bf8dc09 Merge "Do not include genericStds_linux.cpp." 2015-02-18 02:41:47 +00:00
Chih-Hung Hsieh
09f1d04467 Do not include genericStds_linux.cpp.
The __aeabi_memcpy functions are already defined in Android libc.
Redefining them to call memcpy will become recursive when clang/llvm
converts the memcpy call to __aeabi_memcpy.
With this change, we can enable clang/llvm by removing LOCAL_CLANG from Android.mk.

BUG: 12216385
Change-Id: I8b8b4ba7f3ff1e66f8110fc3b6356865a582c1d8
2015-02-12 11:20:14 -08:00
Marco Nelissen
10d211b84a am 1c6ab7db: Merge "Use gcc for the AAC decoder"
* commit '1c6ab7db30867f3eee0d550adb015b340fbbc668':
  Use gcc for the AAC decoder
2015-02-11 01:51:25 +00:00
Marco Nelissen
1c6ab7db30 Merge "Use gcc for the AAC decoder" 2015-02-11 01:22:20 +00:00
Marco Nelissen
355baa79bf Use gcc for the AAC decoder
clang generates crashing code for this.

Change-Id: I90355d6735403290e7c0d93ff4854520b7b80f4a
2015-02-10 15:39:28 -08:00
Chih-Hung Hsieh
28e448bb55 am 66091e46: Merge "Fix checks for {Front,Side,Back}ElementIsCpe"
* commit '66091e46d7aae1b45ed96f5f39274954a296db71':
  Fix checks for {Front,Side,Back}ElementIsCpe
2014-12-01 19:45:05 +00:00
Chih-Hung Hsieh
66091e46d7 Merge "Fix checks for {Front,Side,Back}ElementIsCpe" 2014-12-01 19:31:58 +00:00
Dan Albert
57f76311ba am 84851b23: Merge "Move back to C++98."
* commit '84851b23d6f65ce03da4fa8ef2348b4f46c0ed0f':
  Move back to C++98.
2014-12-01 19:27:01 +00:00
Chih-Hung Hsieh
bb1e78a118 Fix checks for {Front,Side,Back}ElementIsCpe
{Front,Side,Back}ElementIsCpe is an array (per-channel). The check for
pPce->{Front,Side,Back}ElementIsCpe without an index checks the address
of the array, and will always evaluate to true. The elTagSce++
statements are unreachable.

Change-Id: If530371788a44038c500d6f9f7ac67681f77cc71
2014-12-01 11:26:03 -08:00
Dan Albert
84851b23d6 Merge "Move back to C++98." 2014-12-01 19:15:30 +00:00
Dan Albert
d52f374768 Move back to C++98.
This code depends on narrowing hex literals to a signed long, which
trips -Wc++11-narrowing (the fix would be to explicitly cast each
value to signed).

Change-Id: I581a02ef0eeee5a2d95ce0ff2ec6f7ff26f3a074
2014-11-28 13:56:59 -08:00
Chih-Hung Hsieh
1c7368d7c0 am d149516e: am 7e464956: Merge "Move Clang only flags into LOCAL_CLANG_CPPFLAGS."
* commit 'd149516e1a3a63549d2c654b1398544d5de46a3e':
2014-10-25 19:54:26 +00:00
Chih-Hung Hsieh
ab33d4d394 am 7e464956: Merge "Move Clang only flags into LOCAL_CLANG_CPPFLAGS."
* commit '7e46495606bd66973a10565f932acee7bddcc003':
  Move Clang only flags into LOCAL_CLANG_CPPFLAGS.
2014-09-23 16:54:34 +00:00
97 changed files with 4171 additions and 952 deletions

View File

@ -1,31 +1,31 @@
LOCAL_PATH:= $(call my-dir) LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
aacdec_sources := $(wildcard $(LOCAL_PATH)/libAACdec/src/*.cpp) aacdec_sources := $(sort $(wildcard $(LOCAL_PATH)/libAACdec/src/*.cpp))
aacdec_sources := $(aacdec_sources:$(LOCAL_PATH)/libAACdec/src/%=%) aacdec_sources := $(aacdec_sources:$(LOCAL_PATH)/libAACdec/src/%=%)
aacenc_sources := $(wildcard $(LOCAL_PATH)/libAACenc/src/*.cpp) aacenc_sources := $(sort $(wildcard $(LOCAL_PATH)/libAACenc/src/*.cpp))
aacenc_sources := $(aacenc_sources:$(LOCAL_PATH)/libAACenc/src/%=%) aacenc_sources := $(aacenc_sources:$(LOCAL_PATH)/libAACenc/src/%=%)
pcmutils_sources := $(wildcard $(LOCAL_PATH)/libPCMutils/src/*.cpp) pcmutils_sources := $(sort $(wildcard $(LOCAL_PATH)/libPCMutils/src/*.cpp))
pcmutils_sources := $(pcmutils_sources:$(LOCAL_PATH)/libPCMutils/src/%=%) pcmutils_sources := $(pcmutils_sources:$(LOCAL_PATH)/libPCMutils/src/%=%)
fdk_sources := $(wildcard $(LOCAL_PATH)/libFDK/src/*.cpp) fdk_sources := $(sort $(wildcard $(LOCAL_PATH)/libFDK/src/*.cpp))
fdk_sources := $(fdk_sources:$(LOCAL_PATH)/libFDK/src/%=%) fdk_sources := $(fdk_sources:$(LOCAL_PATH)/libFDK/src/%=%)
sys_sources := $(wildcard $(LOCAL_PATH)/libSYS/src/*.cpp) sys_sources := $(sort $(wildcard $(LOCAL_PATH)/libSYS/src/*.cpp))
sys_sources := $(sys_sources:$(LOCAL_PATH)/libSYS/src/%=%) sys_sources := $(sys_sources:$(LOCAL_PATH)/libSYS/src/%=%)
mpegtpdec_sources := $(wildcard $(LOCAL_PATH)/libMpegTPDec/src/*.cpp) mpegtpdec_sources := $(sort $(wildcard $(LOCAL_PATH)/libMpegTPDec/src/*.cpp))
mpegtpdec_sources := $(mpegtpdec_sources:$(LOCAL_PATH)/libMpegTPDec/src/%=%) mpegtpdec_sources := $(mpegtpdec_sources:$(LOCAL_PATH)/libMpegTPDec/src/%=%)
mpegtpenc_sources := $(wildcard $(LOCAL_PATH)/libMpegTPEnc/src/*.cpp) mpegtpenc_sources := $(sort $(wildcard $(LOCAL_PATH)/libMpegTPEnc/src/*.cpp))
mpegtpenc_sources := $(mpegtpenc_sources:$(LOCAL_PATH)/libMpegTPEnc/src/%=%) mpegtpenc_sources := $(mpegtpenc_sources:$(LOCAL_PATH)/libMpegTPEnc/src/%=%)
sbrdec_sources := $(wildcard $(LOCAL_PATH)/libSBRdec/src/*.cpp) sbrdec_sources := $(sort $(wildcard $(LOCAL_PATH)/libSBRdec/src/*.cpp))
sbrdec_sources := $(sbrdec_sources:$(LOCAL_PATH)/libSBRdec/src/%=%) sbrdec_sources := $(sbrdec_sources:$(LOCAL_PATH)/libSBRdec/src/%=%)
sbrenc_sources := $(wildcard $(LOCAL_PATH)/libSBRenc/src/*.cpp) sbrenc_sources := $(sort $(wildcard $(LOCAL_PATH)/libSBRenc/src/*.cpp))
sbrenc_sources := $(sbrenc_sources:$(LOCAL_PATH)/libSBRenc/src/%=%) sbrenc_sources := $(sbrenc_sources:$(LOCAL_PATH)/libSBRenc/src/%=%)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
@ -39,8 +39,8 @@ LOCAL_SRC_FILES := \
$(sbrdec_sources:%=libSBRdec/src/%) \ $(sbrdec_sources:%=libSBRdec/src/%) \
$(sbrenc_sources:%=libSBRenc/src/%) $(sbrenc_sources:%=libSBRenc/src/%)
LOCAL_CFLAGS := -DANDROID
LOCAL_CFLAGS += -Wno-sequence-point -Wno-extra LOCAL_CFLAGS += -Wno-sequence-point -Wno-extra
LOCAL_CFLAGS += "-Wno-\#warnings" -Wno-constant-logical-operand -Wno-self-assign
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/libAACdec/include \ $(LOCAL_PATH)/libAACdec/include \
@ -53,10 +53,6 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/libSBRdec/include \ $(LOCAL_PATH)/libSBRdec/include \
$(LOCAL_PATH)/libSBRenc/include $(LOCAL_PATH)/libSBRenc/include
# In tpdec_asc.cpp: address of array 'pPce->FrontElementIsCpe'
# will always evaluate to 'true'.
LOCAL_CLANG_CPPFLAGS += \
-Wno-pointer-bool-conversion
LOCAL_MODULE:= libFraunhoferAAC LOCAL_MODULE:= libFraunhoferAAC

View File

@ -1,3 +1,12 @@
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 0.1.3
- Updated upstream sources, with a number of crash fixes and new features - Updated upstream sources, with a number of crash fixes and new features
(including support for encoding 7.1) (including support for encoding 7.1)

View File

@ -74,7 +74,6 @@ AACENC_SRC = \
libAACenc/src/pre_echo_control.cpp \ libAACenc/src/pre_echo_control.cpp \
libAACenc/src/quantize.cpp \ libAACenc/src/quantize.cpp \
libAACenc/src/tonality.cpp \ libAACenc/src/tonality.cpp \
libAACenc/src/aacenc_hcr.cpp \
libAACenc/src/aacEnc_rom.cpp \ libAACenc/src/aacEnc_rom.cpp \
libAACenc/src/bandwidth.cpp \ libAACenc/src/bandwidth.cpp \
libAACenc/src/channel_map.cpp \ libAACenc/src/channel_map.cpp \
@ -119,6 +118,7 @@ MPEGTPDEC_SRC = \
libMpegTPDec/src/tpdec_adif.cpp \ libMpegTPDec/src/tpdec_adif.cpp \
libMpegTPDec/src/tpdec_adts.cpp \ libMpegTPDec/src/tpdec_adts.cpp \
libMpegTPDec/src/tpdec_asc.cpp \ libMpegTPDec/src/tpdec_asc.cpp \
libMpegTPDec/src/tpdec_drm.cpp \
libMpegTPDec/src/tpdec_latm.cpp \ libMpegTPDec/src/tpdec_latm.cpp \
libMpegTPDec/src/tpdec_lib.cpp libMpegTPDec/src/tpdec_lib.cpp
@ -186,9 +186,11 @@ libfdk_aac_la_SOURCES = \
EXTRA_DIST = \ EXTRA_DIST = \
$(top_srcdir)/autogen.sh \ $(top_srcdir)/autogen.sh \
$(top_srcdir)/MODULE_LICENSE_FRAUNHOFER \
$(top_srcdir)/NOTICE \ $(top_srcdir)/NOTICE \
$(top_srcdir)/Android.mk \ $(top_srcdir)/Android.mk \
$(top_srcdir)/fdk-aac.sym \ $(top_srcdir)/fdk-aac.sym \
$(top_srcdir)/Makefile.vc \
$(top_srcdir)/documentation/*.pdf \ $(top_srcdir)/documentation/*.pdf \
$(top_srcdir)/libAACdec/src/*.h \ $(top_srcdir)/libAACdec/src/*.h \
$(top_srcdir)/libAACdec/src/arm/*.cpp \ $(top_srcdir)/libAACdec/src/arm/*.cpp \
@ -209,10 +211,12 @@ EXTRA_DIST = \
$(top_srcdir)/libMpegTPDec/src/*.h \ $(top_srcdir)/libMpegTPDec/src/*.h \
$(top_srcdir)/libMpegTPDec/src/version \ $(top_srcdir)/libMpegTPDec/src/version \
$(top_srcdir)/libFDK/include/*.h \ $(top_srcdir)/libFDK/include/*.h \
$(top_srcdir)/libFDK/include/aarch64/*.h \
$(top_srcdir)/libFDK/include/arm/*.h \ $(top_srcdir)/libFDK/include/arm/*.h \
$(top_srcdir)/libFDK/include/mips/*.h \ $(top_srcdir)/libFDK/include/mips/*.h \
$(top_srcdir)/libFDK/include/ppc/*.h \ $(top_srcdir)/libFDK/include/ppc/*.h \
$(top_srcdir)/libFDK/include/x86/*.h \ $(top_srcdir)/libFDK/include/x86/*.h \
$(top_srcdir)/libFDK/src/arm/*.cpp \ $(top_srcdir)/libFDK/src/arm/*.cpp \
$(top_srcdir)/libFDK/src/mips/*.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)

View File

@ -18,7 +18,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#if defined(_MSC_VER)
#include <getopt.h>
#else
#include <unistd.h> #include <unistd.h>
#endif
#include <stdlib.h> #include <stdlib.h>
#include "libAACenc/include/aacenc_lib.h" #include "libAACenc/include/aacenc_lib.h"
#include "wavreader.h" #include "wavreader.h"

View File

@ -1,7 +1,7 @@
dnl -*- Autoconf -*- dnl -*- Autoconf -*-
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_INIT([fdk-aac], [0.1.4], [http://sourceforge.net/projects/opencore-amr/]) AC_INIT([fdk-aac], [0.1.5], [http://sourceforge.net/projects/opencore-amr/])
AC_CONFIG_AUX_DIR(.) AC_CONFIG_AUX_DIR(.)
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([tar-ustar foreign]) AM_INIT_AUTOMAKE([tar-ustar foreign])

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -350,7 +350,7 @@ Where N equals to CStreamInfo::frameSize .
#define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 5 #define AACDECODER_LIB_VL1 5
#define AACDECODER_LIB_VL2 10 #define AACDECODER_LIB_VL2 17
/** /**
* \brief AAC decoder error codes. * \brief AAC decoder error codes.
@ -382,6 +382,7 @@ typedef enum {
not exist. */ not exist. */
AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be
performed. */ performed. */
AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */
aac_dec_init_error_end = 0x2FFF, aac_dec_init_error_end = 0x2FFF,
/* Decode errors. Output buffer is valid but concealed. */ /* Decode errors. Output buffer is valid but concealed. */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -167,6 +167,36 @@ const SCHAR ExponentTable [4][14] =
} ; } ;
/* 41 scfbands */
static const SHORT sfb_96_1024[42] =
{
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
48, 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144,
156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640,
704, 768, 832, 896, 960, 1024
};
/* 12 scfbands */
static const SHORT sfb_96_128[13] =
{
0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92,
128
};
/* 47 scfbands*/
static const SHORT sfb_64_1024[48] =
{
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52,
56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240,
268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784,
824, 864, 904, 944, 984,1024
};
/* 12 scfbands */
static const SHORT sfb_64_128[13] =
{
0, 4, 8, 12, 16, 20, 24,
32, 40, 48, 64, 92, 128
};
/* 49 scfbands */ /* 49 scfbands */
static const SHORT sfb_48_1024[50] = { static const SHORT sfb_48_1024[50] = {
@ -239,6 +269,35 @@ static const SHORT sfb_8_128[16] =
}; };
static const SHORT sfb_96_960[42] =
{
0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
108, 120, 132, 144, 156, 172, 188, 212, 240, 276,
320, 384, 448, 512, 576, 640, 704, 768, 832, 896,
960
}; /* 40 scfbands */
static const SHORT sfb_96_120[13] =
{
0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
64, 92, 120
}; /* 12 scfbands */
static const SHORT sfb_64_960[47] =
{
0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
40, 44, 48, 52, 56, 64, 72, 80, 88, 100,
112, 124, 140, 156, 172, 192, 216, 240, 268, 304,
344, 384, 424, 464, 504, 544, 584, 624, 664, 704,
744, 784, 824, 864, 904, 944, 960
}; /* 46 scfbands */
static const SHORT sfb_64_120[13] =
{
0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
64, 92, 120
}; /* 12 scfbands */
static const SHORT sfb_48_960[50] = static const SHORT sfb_48_960[50] =
{ {
@ -358,9 +417,9 @@ static const SHORT sfb_24_480[31] =
const SFB_INFO sfbOffsetTables[5][16] = const SFB_INFO sfbOffsetTables[5][16] =
{ {
{ {
{ NULL, NULL, 0, 0 }, { sfb_96_1024, sfb_96_128, 41, 12 },
{ NULL, NULL, 0, 0 }, { sfb_96_1024, sfb_96_128, 41, 12 },
{ NULL, NULL, 0, 0 }, { sfb_64_1024, sfb_64_128, 47, 12 },
{ sfb_48_1024, sfb_48_128, 49, 14 }, { sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_48_1024, sfb_48_128, 49, 14 }, { sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_32_1024, sfb_48_128, 51, 14 }, { sfb_32_1024, sfb_48_128, 51, 14 },
@ -372,9 +431,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_8_1024, sfb_8_128, 40, 15 }, { sfb_8_1024, sfb_8_128, 40, 15 },
{ sfb_8_1024, sfb_8_128, 40, 15 }, { sfb_8_1024, sfb_8_128, 40, 15 },
}, { }, {
{ NULL, NULL, 0, 0 }, { sfb_96_960, sfb_96_120, 40, 12 },
{ NULL, NULL, 0, 0 }, { sfb_96_960, sfb_96_120, 40, 12 },
{ NULL, NULL, 0, 0 }, { sfb_64_960, sfb_64_120, 46, 12 },
{ sfb_48_960, sfb_48_120, 49, 14 }, { sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_48_960, sfb_48_120, 49, 14 }, { sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_32_960, sfb_48_120, 49, 14 }, { sfb_32_960, sfb_48_120, 49, 14 },
@ -388,9 +447,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
}, { }, {
{ NULL, NULL, 0, 0 }, { NULL, NULL, 0, 0 },
}, { }, {
{ NULL, NULL, 0, 0 }, { sfb_48_512, NULL, 36, 0 },
{ NULL, NULL, 0, 0 }, { sfb_48_512, NULL, 36, 0 },
{ NULL, NULL, 0, 0 }, { sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0 }, { sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0}, { sfb_48_512, NULL, 36, 0},
{ sfb_32_512, NULL, 37, 0 }, { sfb_32_512, NULL, 37, 0 },
@ -402,9 +461,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_24_512, NULL, 31, 0 }, { sfb_24_512, NULL, 31, 0 },
{ sfb_24_512, NULL, 31, 0 }, { sfb_24_512, NULL, 31, 0 },
}, { }, {
{ NULL, NULL, 0, 0 }, { sfb_48_480, NULL, 35, 0 },
{ NULL, NULL, 0, 0 }, { sfb_48_480, NULL, 35, 0 },
{ NULL, NULL, 0, 0 }, { sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 }, { sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 }, { sfb_48_480, NULL, 35, 0 },
{ sfb_32_480, NULL, 37, 0 }, { sfb_32_480, NULL, 37, 0 },

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -705,7 +705,7 @@ static int aacDecoder_drcExtractAndMap (
} }
self->numPayloads = 0; self->numPayloads = 0;
if (self->dvbAncDataAvailable) if (self->dvbAncDataAvailable && self->numThreads < MAX_DRC_THREADS)
{ /* Append a DVB heavy compression payload thread if available. */ { /* Append a DVB heavy compression payload thread if available. */
int bitsParsed; int bitsParsed;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -157,23 +157,9 @@ amm-info@iis.fraunhofer.de
#include "conceal.h" #include "conceal.h"
#include "FDK_crc.h"
#define CAN_DO_PS(aot) \
((aot) == AOT_AAC_LC \
|| (aot) == AOT_SBR \
|| (aot) == AOT_PS \
|| (aot) == AOT_ER_BSAC \
|| (aot) == AOT_DRM_AAC)
#define IS_USAC(aot) \
((aot) == AOT_USAC \
|| (aot) == AOT_RSVD50)
#define IS_LOWDELAY(aot) \
((aot) == AOT_ER_AAC_LD \
|| (aot) == AOT_ER_AAC_ELD)
void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self) void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self)
{ {
@ -552,8 +538,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
previous_element, previous_element,
elIndex, elIndex,
self->flags & AC_INDEP ); self->flags & AC_INDEP );
/* Enable SBR for implicit SBR signalling. */ /* Enable SBR for implicit SBR signalling but only if no severe error happend. */
if (sbrError == SBRDEC_OK) { if ( (sbrError == SBRDEC_OK)
|| (sbrError == SBRDEC_PARSE_ERROR) ) {
self->sbrEnabled = 1; self->sbrEnabled = 1;
} }
} else { } else {
@ -568,7 +555,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
FDKpushBiDirectional(hBs, *count); FDKpushBiDirectional(hBs, *count);
*count = 0; *count = 0;
} else { } else {
/* If this is not a fill element with a known length, we are screwed an no further parsing makes sense. */ /* If this is not a fill element with a known length, we are screwed and further parsing makes no sense. */
if (sbrError != SBRDEC_OK) { if (sbrError != SBRDEC_OK) {
self->frameOK = 0; self->frameOK = 0;
} }
@ -847,12 +834,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
switch (asc->m_aot) { switch (asc->m_aot) {
case AOT_AAC_LC: case AOT_AAC_LC:
self->streamInfo.profile = 1; self->streamInfo.profile = 1;
break;
case AOT_ER_AAC_SCAL:
if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) {
/* aac_scalable_extension_element() currently not supported. */
return AAC_DEC_UNSUPPORTED_FORMAT;
}
case AOT_SBR: case AOT_SBR:
case AOT_PS: case AOT_PS:
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
case AOT_DRM_AAC:
break; break;
default: default:
@ -972,11 +965,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
if (asc->m_aot == AOT_ER_AAC_ELD) { if (asc->m_aot == AOT_ER_AAC_ELD) {
self->flags |= AC_ELD; self->flags |= AC_ELD;
self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; /* Need to set the SBR flag for backward-compatibility
reasons. Even if SBR is not supported. */
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0; self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0; self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0;
} }
self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0; self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
if ( asc->m_aot == AOT_DRM_AAC ) {
self->flags |= AC_DRM|AC_SBRCRC|AC_SCALABLE;
}
if ( (asc->m_aot == AOT_AAC_SCAL)
|| (asc->m_aot == AOT_ER_AAC_SCAL) ) {
self->flags |= AC_SCALABLE;
}
if (asc->m_sbrPresentFlag) { if (asc->m_sbrPresentFlag) {
@ -1162,6 +1164,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Check sampling frequency */ /* Check sampling frequency */
switch ( self->streamInfo.aacSampleRate ) { switch ( self->streamInfo.aacSampleRate ) {
case 96000:
case 88200:
case 64000:
case 16000: case 16000:
case 12000: case 12000:
case 11025: case 11025:
@ -1490,7 +1495,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* get the remaining bits of this frame */ /* get the remaining bits of this frame */
bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0); bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) ) if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_DRM)) )
{ {
SBR_ERROR err = SBRDEC_OK; SBR_ERROR err = SBRDEC_OK;
int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE]; int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
@ -1528,6 +1533,13 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
} }
if (self->flags & AC_DRM)
{
if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
FDKpushBiDirectional(bs, bitCnt);
}
}
if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) ) if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) )
{ {
while ( bitCnt > 7 ) { while ( bitCnt > 7 ) {

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -226,6 +226,8 @@ struct AAC_DECODER_INSTANCE {
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */ FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */ UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
INT_PCM pcmOutputBuffer[(8)*(2048)];
}; };

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -110,10 +110,15 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 5 #define AACDECODER_LIB_VL1 5
#define AACDECODER_LIB_VL2 10 #define AACDECODER_LIB_VL2 17
#define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__
#define AACDECODER_LIB_BUILD_DATE ""
#define AACDECODER_LIB_BUILD_TIME ""
#else
#define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_DATE __DATE__
#define AACDECODER_LIB_BUILD_TIME __TIME__ #define AACDECODER_LIB_BUILD_TIME __TIME__
#endif
static AAC_DECODER_ERROR static AAC_DECODER_ERROR
setConcealMethod ( const HANDLE_AACDECODER self, setConcealMethod ( const HANDLE_AACDECODER self,
@ -176,8 +181,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw (
break; break;
} }
/* if baselayer is OK we continue decoding */ /* if baselayer is OK we continue decoding */
if(layer >= 1){ if(layer >= 1){
self->nrOfLayers = layer; self->nrOfLayers = layer;
err = AAC_DEC_OK;
} }
break; break;
} }
@ -780,8 +786,8 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self)
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_AACDECODER self, HANDLE_AACDECODER self,
INT_PCM *pTimeData, INT_PCM *pTimeData_extern,
const INT timeDataSize, const INT timeDataSize_extern,
const UINT flags) const UINT flags)
{ {
AAC_DECODER_ERROR ErrorStatus; AAC_DECODER_ERROR ErrorStatus;
@ -791,12 +797,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_FDK_BITSTREAM hBs; HANDLE_FDK_BITSTREAM hBs;
int fTpInterruption = 0; /* Transport originated interruption detection. */ int fTpInterruption = 0; /* Transport originated interruption detection. */
int fTpConceal = 0; /* Transport originated concealment. */ int fTpConceal = 0; /* Transport originated concealment. */
INT_PCM *pTimeData = NULL;
INT timeDataSize = 0;
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; return AAC_DEC_INVALID_HANDLE;
} }
pTimeData = self->pcmOutputBuffer;
timeDataSize = sizeof(self->pcmOutputBuffer)/sizeof(*self->pcmOutputBuffer);
if (flags & AACDEC_INTR) { if (flags & AACDEC_INTR) {
self->streamInfo.numLostAccessUnits = 0; self->streamInfo.numLostAccessUnits = 0;
} }
@ -913,7 +924,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
if (self->sbrEnabled) if (self->sbrEnabled)
{ {
SBR_ERROR sbrError = SBRDEC_OK; SBR_ERROR sbrError = SBRDEC_OK;
int chOutMapIdx = ((self->chMapIndex==0) && (self->streamInfo.numChannels<7)) ? self->streamInfo.numChannels : self->chMapIndex; int chIdx, numCoreChannel = self->streamInfo.numChannels;
int chOutMapIdx = ((self->chMapIndex==0) && (numCoreChannel<7)) ? numCoreChannel : self->chMapIndex;
/* set params */ /* set params */
sbrDecoder_SetParam ( self->hSbrDecoder, sbrDecoder_SetParam ( self->hSbrDecoder,
@ -973,10 +985,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
if (self->psPossible) { if (self->psPossible) {
self->flags |= AC_PS_PRESENT; self->flags |= AC_PS_PRESENT;
self->channelType[0] = ACT_FRONT; }
self->channelType[1] = ACT_FRONT; for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; chIdx+=1) {
self->channelIndices[0] = 0; self->channelType[chIdx] = ACT_FRONT;
self->channelIndices[1] = 1; self->channelIndices[chIdx] = chIdx;
} }
} }
} }
@ -1001,7 +1013,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
self->channelOutputMapping, self->channelOutputMapping,
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL (self->limiterEnableCurr) ? &pcmLimiterScale : NULL
); );
if (dmxErr == PCMDMX_INVALID_MODE) { if ( (ErrorStatus == AAC_DEC_OK)
&& (dmxErr == PCMDMX_INVALID_MODE) ) {
/* Announce the framework that the current combination of channel configuration and downmix /* Announce the framework that the current combination of channel configuration and downmix
* settings are not know to produce a predictable behavior and thus maybe produce strange output. */ * settings are not know to produce a predictable behavior and thus maybe produce strange output. */
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
@ -1046,6 +1059,19 @@ bail:
/* Update Statistics */ /* Update Statistics */
aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus); aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus);
/* Check whether external output buffer is large enough. */
if (timeDataSize_extern < self->streamInfo.numChannels*self->streamInfo.frameSize) {
ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
}
/* Update external output buffer. */
if ( IS_OUTPUT_VALID(ErrorStatus) ) {
FDKmemcpy(pTimeData_extern, pTimeData, self->streamInfo.numChannels*self->streamInfo.frameSize*sizeof(*pTimeData));
}
else {
FDKmemclear(pTimeData_extern, timeDataSize_extern*sizeof(*pTimeData_extern));
}
return ErrorStatus; return ErrorStatus;
} }
@ -1115,6 +1141,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
/* Set flags */ /* Set flags */
info->flags = 0 info->flags = 0
| CAPF_AAC_LC | CAPF_AAC_LC
| CAPF_ER_AAC_SCAL
| CAPF_AAC_VCB11 | CAPF_AAC_VCB11
| CAPF_AAC_HCR | CAPF_AAC_HCR
| CAPF_AAC_RVLC | CAPF_AAC_RVLC
@ -1125,6 +1152,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
| CAPF_AAC_MPEG4 | CAPF_AAC_MPEG4
| CAPF_AAC_DRM_BSFORMAT
| CAPF_AAC_1024 | CAPF_AAC_1024
| CAPF_AAC_960 | CAPF_AAC_960

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -324,13 +324,12 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
if (flags & AC_ER_HCR) { if (flags & AC_ER_HCR) {
/* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */ /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
numLinesInSecIdx++;
if (numLinesInSecIdx >= MAX_SFB_HCR) { if (numLinesInSecIdx >= MAX_SFB_HCR) {
return AAC_DEC_PARSE_ERROR; return AAC_DEC_PARSE_ERROR;
} }
if ( pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
(sect_cb == BOOKSCL) ) numLinesInSecIdx++;
if (sect_cb == BOOKSCL)
{ {
return AAC_DEC_INVALID_CODE_BOOK; return AAC_DEC_INVALID_CODE_BOOK;
} else { } else {

View File

@ -459,7 +459,7 @@ void BidirectionalEstimation_UseScfOfPrevFrameAsReference (
break; break;
case NOISE_HCB: case NOISE_HCB:
if ( (pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==NOISE_HCB) ) { if ( pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==NOISE_HCB ) {
commonMin = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); commonMin = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]);
pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]);
} else { } else {
@ -669,7 +669,7 @@ void PredictiveInterpolation (
break; break;
case NOISE_HCB: case NOISE_HCB:
if ( (pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==NOISE_HCB) ) { if ( pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==NOISE_HCB ) {
commonMin = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); commonMin = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]);
pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]);
} }

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -707,7 +707,7 @@ the encoder deactivates PNS calculation internally.
#define AACENCODER_LIB_VL0 3 #define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4 #define AACENCODER_LIB_VL1 4
#define AACENCODER_LIB_VL2 12 #define AACENCODER_LIB_VL2 22
/** /**
* AAC encoder error codes. * AAC encoder error codes.
@ -900,11 +900,7 @@ typedef enum
This configuration can be used only with stereo input audio data. This configuration can be used only with stereo input audio data.
- 23: MPEG-4 AAC Low-Delay. - 23: MPEG-4 AAC Low-Delay.
- 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no ::AUDIO_OBJECT_TYPE for ELD in - 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no ::AUDIO_OBJECT_TYPE for ELD in
combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. */
- 129: MPEG-2 AAC Low Complexity.
- 132: MPEG-2 AAC Low Complexity with Spectral Band Replication (HE-AAC).
- 156: MPEG-2 AAC Low Complexity with Spectral Band Replication and Parametric Stereo (HE-AAC v2).
This configuration can be used only with stereo input audio data. */
AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is mandatory and interacts with ::AACENC_BITRATEMODE. AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is mandatory and interacts with ::AACENC_BITRATEMODE.
- CBR: Bitrate in bits/second. - CBR: Bitrate in bits/second.
@ -961,6 +957,16 @@ typedef enum
- 1 to fs/2: Frequency bandwidth in Hertz. (Experts only, better do not - 1 to fs/2: Frequency bandwidth in Hertz. (Experts only, better do not
touch this value to avoid degraded audio quality) */ touch this value to avoid degraded audio quality) */
AACENC_PEAK_BITRATE = 0x0207, /*!< Peak bitrate configuration parameter to adjust maximum bits per audio frame. Bitrate is in bits/second.
The peak bitrate will internally be limited to the chosen bitrate ::AACENC_BITRATE as lower limit
and the number_of_effective_channels*6144 bit as upper limit.
Setting the peak bitrate equal to ::AACENC_BITRATE does not necessarily mean that the audio frames
will be of constant size. Since the peak bitate is in bits/second, the frame sizes can vary by
one byte in one or the other direction over various frames. However, it is not recommended to reduce
the peak pitrate to ::AACENC_BITRATE - it would disable the bitreservoir, which would affect the
audio quality by a large amount. */
AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE in FDK_audio.h. Following AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE in FDK_audio.h. Following
types can be configured in encoder library: types can be configured in encoder library:
- 0: raw access units - 0: raw access units
@ -1026,6 +1032,11 @@ typedef enum
- ADTS: Maximum number of sub frames restricted to 4. - ADTS: Maximum number of sub frames restricted to 4.
- LOAS/LATM: Maximum number of sub frames restricted to 2.*/ - LOAS/LATM: Maximum number of sub frames restricted to 2.*/
AACENC_AUDIOMUXVER = 0x0304, /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, currently not implemented):
- 0: Default, no transmission of tara Buffer fullness, no ASC length and including actual latm Buffer fullnes.
- 1: Transmission of tara Buffer fullness, ASC length and actual latm Buffer fullness.
- 2: Transmission of tara Buffer fullness, ASC length and maximum level of latm Buffer fullness. */
AACENC_PROTECTION = 0x0306, /*!< Configure protection in tranpsort layer: AACENC_PROTECTION = 0x0306, /*!< Configure protection in tranpsort layer:
- 0: No protection. (default) - 0: No protection. (default)
- 1: CRC active for ADTS bitstream format. */ - 1: CRC active for ADTS bitstream format. */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de
/* /*
Huffman Tables Huffman Tables
*/ */
const INT FDKaacEnc_huff_ltab1_2[3][3][3][3]= const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]=
{ {
{ {
{ {0x000b0009,0x00090007,0x000b0009}, {0x000a0008,0x00070006,0x000a0008}, {0x000b0009,0x00090008,0x000b0009} }, { {0x000b0009,0x00090007,0x000b0009}, {0x000a0008,0x00070006,0x000a0008}, {0x000b0009,0x00090008,0x000b0009} },
@ -113,7 +113,7 @@ const INT FDKaacEnc_huff_ltab1_2[3][3][3][3]=
}; };
const INT FDKaacEnc_huff_ltab3_4[3][3][3][3]= const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]=
{ {
{ {
{ {0x00010004,0x00040005,0x00080008}, {0x00040005,0x00050004,0x00080008}, {0x00090009,0x00090008,0x000a000b} }, { {0x00010004,0x00040005,0x00080008}, {0x00040005,0x00050004,0x00080008}, {0x00090009,0x00090008,0x000a000b} },
@ -132,7 +132,7 @@ const INT FDKaacEnc_huff_ltab3_4[3][3][3][3]=
} }
}; };
const INT FDKaacEnc_huff_ltab5_6[9][9]= const ULONG FDKaacEnc_huff_ltab5_6[9][9]=
{ {
{0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c000a, 0x000d000b}, {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c000a, 0x000d000b},
{0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0008, 0x000b0009, 0x000c000a}, {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0008, 0x000b0009, 0x000c000a},
@ -145,7 +145,7 @@ const INT FDKaacEnc_huff_ltab5_6[9][9]=
{0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, 0x000b0009, 0x000c000a, 0x000d000b} {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, 0x000b0009, 0x000c000a, 0x000d000b}
}; };
const INT FDKaacEnc_huff_ltab7_8[8][8]= const ULONG FDKaacEnc_huff_ltab7_8[8][8]=
{ {
{0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, 0x000a0009, 0x000b000a}, {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, 0x000a0009, 0x000b000a},
{0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x00090008}, {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x00090008},
@ -157,7 +157,7 @@ const INT FDKaacEnc_huff_ltab7_8[8][8]=
{0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c000a} {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c000a}
}; };
const INT FDKaacEnc_huff_ltab9_10[13][13]= const ULONG FDKaacEnc_huff_ltab9_10[13][13]=
{ {
{0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, 0x000d000c}, {0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, 0x000d000c},
{0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, 0x000c000b}, {0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, 0x000c000b},
@ -392,7 +392,7 @@ const USHORT FDKaacEnc_huff_ctab11[21][17]=
{0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021} {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021}
}; };
const INT FDKaacEnc_huff_ctabscf[121]= const ULONG FDKaacEnc_huff_ctabscf[121]=
{ {
0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, 0x0007ffed, 0x0007fff6, 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, 0x0007ffed, 0x0007fff6,
0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7,
@ -657,11 +657,11 @@ const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = {
*/ */
const FIXP_DBL FDKaacEnc_tnsEncCoeff3[8]= const FIXP_DBL FDKaacEnc_tnsEncCoeff3[8]=
{ {
0x81f1d201, 0x91261481, 0xadb92301, 0xd438af00, 0x00000000, 0x37898080, 0x64130dff, 0x7cca6fff (FIXP_DBL)0x81f1d201, (FIXP_DBL)0x91261481, (FIXP_DBL)0xadb92301, (FIXP_DBL)0xd438af00, (FIXP_DBL)0x00000000, (FIXP_DBL)0x37898080, (FIXP_DBL)0x64130dff, (FIXP_DBL)0x7cca6fff
}; };
const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={ const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={
0x80000001 /*-4*/, 0x87b826df /*-3*/, 0x9df24154 /*-2*/, 0xbfffffe5 /*-1*/, (FIXP_DBL)0x80000001 /*-4*/, (FIXP_DBL)0x87b826df /*-3*/, (FIXP_DBL)0x9df24154 /*-2*/, (FIXP_DBL)0xbfffffe5 /*-1*/,
0xe9c5e578 /* 0*/, 0x1c7b90f0 /* 1*/, 0x4fce83a9 /* 2*/, 0x7352f2c3 /* 3*/ (FIXP_DBL)0xe9c5e578 /* 0*/, (FIXP_DBL)0x1c7b90f0 /* 1*/, (FIXP_DBL)0x4fce83a9 /* 2*/, (FIXP_DBL)0x7352f2c3 /* 3*/
}; };
/* /*
@ -669,15 +669,15 @@ const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={
*/ */
const FIXP_DBL FDKaacEnc_tnsEncCoeff4[16]= const FIXP_DBL FDKaacEnc_tnsEncCoeff4[16]=
{ {
0x808bc881, 0x84e2e581, 0x8d6b4a01, 0x99da9201, 0xa9c45701, 0xbc9dde81, 0xd1c2d500, 0xe87ae540, (FIXP_DBL)0x808bc881, (FIXP_DBL)0x84e2e581, (FIXP_DBL)0x8d6b4a01, (FIXP_DBL)0x99da9201, (FIXP_DBL)0xa9c45701, (FIXP_DBL)0xbc9dde81, (FIXP_DBL)0xd1c2d500, (FIXP_DBL)0xe87ae540,
0x00000000, 0x1a9cd9c0, 0x340ff240, 0x4b3c8bff, 0x5f1f5e7f, 0x6ed9eb7f, 0x79bc387f, 0x7f4c7e7f (FIXP_DBL)0x00000000, (FIXP_DBL)0x1a9cd9c0, (FIXP_DBL)0x340ff240, (FIXP_DBL)0x4b3c8bff, (FIXP_DBL)0x5f1f5e7f, (FIXP_DBL)0x6ed9eb7f, (FIXP_DBL)0x79bc387f, (FIXP_DBL)0x7f4c7e7f
}; };
const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]= const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]=
{ {
0x80000001 /*-8*/, 0x822deff0 /*-7*/, 0x88a4bfe6 /*-6*/, 0x932c159d /*-5*/, (FIXP_DBL)0x80000001 /*-8*/, (FIXP_DBL)0x822deff0 /*-7*/, (FIXP_DBL)0x88a4bfe6 /*-6*/, (FIXP_DBL)0x932c159d /*-5*/,
0xa16827c2 /*-4*/, 0xb2dcde27 /*-3*/, 0xc6f20b91 /*-2*/, 0xdcf89c64 /*-1*/, (FIXP_DBL)0xa16827c2 /*-4*/, (FIXP_DBL)0xb2dcde27 /*-3*/, (FIXP_DBL)0xc6f20b91 /*-2*/, (FIXP_DBL)0xdcf89c64 /*-1*/,
0xf4308ce1 /* 0*/, 0x0d613054 /* 1*/, 0x278dde80 /* 2*/, 0x4000001b /* 3*/, (FIXP_DBL)0xf4308ce1 /* 0*/, (FIXP_DBL)0x0d613054 /* 1*/, (FIXP_DBL)0x278dde80 /* 2*/, (FIXP_DBL)0x4000001b /* 3*/,
0x55a6127b /* 4*/, 0x678dde8f /* 5*/, 0x74ef0ed7 /* 6*/, 0x7d33f0da /* 7*/ (FIXP_DBL)0x55a6127b /* 4*/, (FIXP_DBL)0x678dde8f /* 5*/, (FIXP_DBL)0x74ef0ed7 /* 6*/, (FIXP_DBL)0x7d33f0da /* 7*/
}; };
const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512]={ const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512]={
FL2FXCONST_DBL(0.3968502629920499),FL2FXCONST_DBL(0.3978840634868335),FL2FXCONST_DBL(0.3989185359354711),FL2FXCONST_DBL(0.3999536794661432), FL2FXCONST_DBL(0.3968502629920499),FL2FXCONST_DBL(0.3978840634868335),FL2FXCONST_DBL(0.3989185359354711),FL2FXCONST_DBL(0.3999536794661432),

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -105,11 +105,11 @@ amm-info@iis.fraunhofer.de
/* /*
Huffman Tables Huffman Tables
*/ */
extern const INT FDKaacEnc_huff_ltab1_2[3][3][3][3]; extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3];
extern const INT FDKaacEnc_huff_ltab3_4[3][3][3][3]; extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3];
extern const INT FDKaacEnc_huff_ltab5_6[9][9]; extern const ULONG FDKaacEnc_huff_ltab5_6[9][9];
extern const INT FDKaacEnc_huff_ltab7_8[8][8]; extern const ULONG FDKaacEnc_huff_ltab7_8[8][8];
extern const INT FDKaacEnc_huff_ltab9_10[13][13]; extern const ULONG FDKaacEnc_huff_ltab9_10[13][13];
extern const UCHAR FDKaacEnc_huff_ltab11[17][17]; extern const UCHAR FDKaacEnc_huff_ltab11[17][17];
extern const UCHAR FDKaacEnc_huff_ltabscf[121]; extern const UCHAR FDKaacEnc_huff_ltabscf[121];
extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3]; extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3];
@ -123,7 +123,7 @@ extern const USHORT FDKaacEnc_huff_ctab8[8][8];
extern const USHORT FDKaacEnc_huff_ctab9[13][13]; extern const USHORT FDKaacEnc_huff_ctab9[13][13];
extern const USHORT FDKaacEnc_huff_ctab10[13][13]; extern const USHORT FDKaacEnc_huff_ctab10[13][13];
extern const USHORT FDKaacEnc_huff_ctab11[21][17]; extern const USHORT FDKaacEnc_huff_ctab11[21][17];
extern const INT FDKaacEnc_huff_ctabscf[121]; extern const ULONG FDKaacEnc_huff_ctabscf[121];
/* /*
quantizer quantizer

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -107,6 +107,39 @@ amm-info@iis.fraunhofer.de
#define MIN_BUFSIZE_PER_EFF_CHAN 6144 #define MIN_BUFSIZE_PER_EFF_CHAN 6144
INT FDKaacEnc_CalcBitsPerFrame(
const INT bitRate,
const INT frameLength,
const INT samplingRate
)
{
int shift = 0;
while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength
&& (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate)
{
shift++;
}
return (bitRate*(frameLength>>shift)) / (samplingRate>>shift);
}
INT FDKaacEnc_CalcBitrate(
const INT bitsPerFrame,
const INT frameLength,
const INT samplingRate
)
{
int shift = 0;
while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength
&& (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate)
{
shift++;
}
return (bitsPerFrame * (samplingRate>>shift)) / ( frameLength>>shift) ;
}
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate,
INT framelength, INT framelength,
INT ancillaryRate, INT ancillaryRate,
@ -220,21 +253,19 @@ INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode)
/** /**
* \brief Convert encoder bitreservoir value for transport library. * \brief Convert encoder bitreservoir value for transport library.
* *
* \param bitrateMode Bitratemode used in current encoder instance. Se ::AACENC_BITRATE_MODE * \param hAacEnc Encoder handle
* \param bitresTotal Encoder bitreservoir level in bits.
* *
* \return Corrected bitreservoir level used in transport library. * \return Corrected bitreservoir level used in transport library.
*/ */
static INT FDKaacEnc_EncBitresToTpBitres( static INT FDKaacEnc_EncBitresToTpBitres(
const AACENC_BITRATE_MODE bitrateMode, const HANDLE_AAC_ENC hAacEnc
const INT bitresTotal
) )
{ {
INT transporBitreservoir = 0; INT transporBitreservoir = 0;
switch (bitrateMode) { switch (hAacEnc->bitrateMode) {
case AACENC_BR_MODE_CBR: case AACENC_BR_MODE_CBR:
transporBitreservoir = bitresTotal; /* encoder bitreservoir level */ transporBitreservoir = hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
break; break;
case AACENC_BR_MODE_VBR_1: case AACENC_BR_MODE_VBR_1:
case AACENC_BR_MODE_VBR_2: case AACENC_BR_MODE_VBR_2:
@ -253,6 +284,10 @@ static INT FDKaacEnc_EncBitresToTpBitres(
FDK_ASSERT(0); FDK_ASSERT(0);
} }
if (hAacEnc->config->audioMuxVersion==2) {
transporBitreservoir = MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
}
return transporBitreservoir; return transporBitreservoir;
} }
@ -289,6 +324,7 @@ void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config)
config->minBitsPerFrame = -1; /* minum number of bits in each AU */ config->minBitsPerFrame = -1; /* minum number of bits in each AU */
config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
config->bitreservoir = -1; /* default, uninitialized value */ config->bitreservoir = -1; /* default, uninitialized value */
config->audioMuxVersion = -1; /* audio mux version not configured */
/* init tabs in fixpoint_math */ /* init tabs in fixpoint_math */
InitLdInt(); InitLdInt();
@ -435,7 +471,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
&averageBitsPerFrame, &averageBitsPerFrame,
config->bitrateMode, config->bitrateMode,
config->nSubFrames config->nSubFrames
) != config->bitRate ) ) != config->bitRate
&& !((config->bitrateMode>=1) && (config->bitrateMode<=5))
)
{ {
return AAC_ENC_UNSUPPORTED_BITRATE; return AAC_ENC_UNSUPPORTED_BITRATE;
} }
@ -562,7 +600,10 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
qcInit.averageBits = (averageBitsPerFrame+7)&~7; qcInit.averageBits = (averageBitsPerFrame+7)&~7;
qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff;
qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff;
qcInit.minBits = 0; qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits;
qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame+7)&~7);
qcInit.minBits = (config->minBitsPerFrame!=-1) ? config->minBitsPerFrame : 0;
qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame&~7);
} }
else else
{ {
@ -573,9 +614,11 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes); qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes);
qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits;
qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, fixMax(qcInit.maxBits, (averageBitsPerFrame+7+8)&~7));
qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes)); qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes));
qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits; qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits;
qcInit.minBits = fixMin(qcInit.minBits, (averageBitsPerFrame - transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits))&~7);
} }
qcInit.sampleRate = config->sampleRate; qcInit.sampleRate = config->sampleRate;
@ -583,11 +626,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
qcInit.nSubFrames = config->nSubFrames; qcInit.nSubFrames = config->nSubFrames;
qcInit.padding.paddingRest = config->sampleRate; qcInit.padding.paddingRest = config->sampleRate;
/* Calc meanPe */ /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
bw_ratio = fDivNorm((FIXP_DBL)hAacEnc->bandwidth90dB, (FIXP_DBL)(config->sampleRate>>1), &qbw); bw_ratio = fDivNorm((FIXP_DBL)(10*config->framelength*hAacEnc->bandwidth90dB), (FIXP_DBL)(config->sampleRate), &qbw);
qbw = DFRACT_BITS-1-qbw; qcInit.meanPe = FDKmax((INT)scaleValue(bw_ratio, qbw+1-(DFRACT_BITS-1)), 1);
/* qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
qcInit.meanPe = fMult(bw_ratio, (FIXP_DBL)((10*config->framelength)<<16)) >> (qbw-15);
/* Calc maxBitFac */ /* Calc maxBitFac */
mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac); mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac);
@ -649,23 +690,7 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
if (ErrorStatus != AAC_ENC_OK) if (ErrorStatus != AAC_ENC_OK)
goto bail; goto bail;
/* Map virtual aot's to intern aot used in bitstream writer. */ hAacEnc->aot = hAacEnc->config->audioObjectType;
switch (hAacEnc->config->audioObjectType) {
case AOT_MP2_AAC_LC:
case AOT_DABPLUS_AAC_LC:
hAacEnc->aot = AOT_AAC_LC;
break;
case AOT_MP2_SBR:
case AOT_DABPLUS_SBR:
hAacEnc->aot = AOT_SBR;
break;
case AOT_MP2_PS:
case AOT_DABPLUS_PS:
hAacEnc->aot = AOT_PS;
break;
default:
hAacEnc->aot = hAacEnc->config->audioObjectType;
}
/* common things */ /* common things */
@ -930,7 +955,7 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc,
transportEnc_WriteAccessUnit( transportEnc_WriteAccessUnit(
hTpEnc, hTpEnc,
totalBits, totalBits,
FDKaacEnc_EncBitresToTpBitres(hAacEnc->bitrateMode, hAacEnc->qcKernel->bitResTot), FDKaacEnc_EncBitresToTpBitres(hAacEnc),
cm->nChannelsEff); cm->nChannelsEff);
/* write bitstream */ /* write bitstream */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -98,6 +98,11 @@ amm-info@iis.fraunhofer.de
#include "sbr_encoder.h" #include "sbr_encoder.h"
#define BITRES_MAX_LD 4000
#define BITRES_MIN_LD 500
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -205,6 +210,8 @@ struct AACENC_CONFIG {
INT maxBitsPerFrame; /* maximum number of bits in AU */ INT maxBitsPerFrame; /* maximum number of bits in AU */
INT bitreservoir; /* size of bitreservoir */ INT bitreservoir; /* size of bitreservoir */
INT audioMuxVersion; /* audio mux version in loas/latm transport format */
UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */
UCHAR useTns; /* flag: use temporal noise shaping */ UCHAR useTns; /* flag: use temporal noise shaping */
@ -223,6 +230,36 @@ typedef struct {
typedef struct AAC_ENC *HANDLE_AAC_ENC; typedef struct AAC_ENC *HANDLE_AAC_ENC;
/**
* \brief Calculate framesize in bits for given bit rate, frame length and sampling rate.
*
* \param bitRate Ttarget bitrate in bits per second.
* \param frameLength Number of audio samples in one frame.
* \param samplingRate Sampling rate in Hz.
*
* \return Framesize in bits per frame.
*/
INT FDKaacEnc_CalcBitsPerFrame(
const INT bitRate,
const INT frameLength,
const INT samplingRate
);
/**
* \brief Calculate bitrate in bits per second for given framesize, frame length and sampling rate.
*
* \param bitsPerFrame Framesize in bits per frame.
* \param frameLength Number of audio samples in one frame.
* \param samplingRate Sampling rate in Hz.
*
* \return Bitrate in bits per second.
*/
INT FDKaacEnc_CalcBitrate(
const INT bitsPerFrame,
const INT frameLength,
const INT samplingRate
);
/** /**
* \brief Limit given bit rate to a valid value * \brief Limit given bit rate to a valid value
* \param hTpEnc transport encoder handle * \param hTpEnc transport encoder handle

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -98,10 +98,15 @@ amm-info@iis.fraunhofer.de
/* Encoder library info */ /* Encoder library info */
#define AACENCODER_LIB_VL0 3 #define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4 #define AACENCODER_LIB_VL1 4
#define AACENCODER_LIB_VL2 12 #define AACENCODER_LIB_VL2 22
#define AACENCODER_LIB_TITLE "AAC Encoder" #define AACENCODER_LIB_TITLE "AAC Encoder"
#ifdef __ANDROID__
#define AACENCODER_LIB_BUILD_DATE ""
#define AACENCODER_LIB_BUILD_TIME ""
#else
#define AACENCODER_LIB_BUILD_DATE __DATE__ #define AACENCODER_LIB_BUILD_DATE __DATE__
#define AACENCODER_LIB_BUILD_TIME __TIME__ #define AACENCODER_LIB_BUILD_TIME __TIME__
#endif
#include "sbr_encoder.h" #include "sbr_encoder.h"
@ -148,6 +153,7 @@ typedef struct {
UINT userAfterburner; UINT userAfterburner;
UINT userFramelength; UINT userFramelength;
UINT userAncDataRate; UINT userAncDataRate;
UINT userPeakBitrate;
UCHAR userTns; /*!< Use TNS coding. */ UCHAR userTns; /*!< Use TNS coding. */
UCHAR userPns; /*!< Use PNS coding. */ UCHAR userPns; /*!< Use PNS coding. */
@ -298,7 +304,7 @@ static AACENC_ERROR eldSbrConfigurator(
int i, cfgIdx = -1; int i, cfgIdx = -1;
const ULONG channelBitrate = totalBitrate / FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff; const ULONG channelBitrate = totalBitrate / FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
for (i=0; i<(sizeof(eldSbrAutoConfigTab)/sizeof(ELD_SBR_CONFIGURATOR)); i++) { for (i=0; i<(int)(sizeof(eldSbrAutoConfigTab)/sizeof(ELD_SBR_CONFIGURATOR)); i++) {
if ( (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) if ( (samplingRate <= eldSbrAutoConfigTab[i].samplingRate)
&& (channelBitrate >= eldSbrAutoConfigTab[i].bitrateRange) ) && (channelBitrate >= eldSbrAutoConfigTab[i].bitrateRange) )
{ {
@ -321,10 +327,7 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)
{ {
INT sbrUsed = 0; INT sbrUsed = 0;
if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) )
|| (hAacConfig->audioObjectType==AOT_MP2_SBR) || (hAacConfig->audioObjectType==AOT_MP2_PS)
|| (hAacConfig->audioObjectType==AOT_DABPLUS_SBR) || (hAacConfig->audioObjectType==AOT_DABPLUS_PS)
|| (hAacConfig->audioObjectType==AOT_DRM_SBR) || (hAacConfig->audioObjectType==AOT_DRM_MPEG_PS) )
{ {
sbrUsed = 1; sbrUsed = 1;
} }
@ -340,10 +343,7 @@ static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)
{ {
INT psUsed = 0; INT psUsed = 0;
if ( (audioObjectType==AOT_PS) if ( (audioObjectType==AOT_PS) )
|| (audioObjectType==AOT_MP2_PS)
|| (audioObjectType==AOT_DABPLUS_PS)
|| (audioObjectType==AOT_DRM_MPEG_PS) )
{ {
psUsed = 1; psUsed = 1;
} }
@ -368,8 +368,7 @@ static SBR_PS_SIGNALING getSbrSignalingMode(
sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */ sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */
} }
if ((audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) || if ( (audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ) {
(audioObjectType==AOT_MP2_AAC_LC) || (audioObjectType==AOT_MP2_SBR) || (audioObjectType==AOT_MP2_PS) ) {
switch (transportType) { switch (transportType) {
case TT_MP4_ADIF: case TT_MP4_ADIF:
case TT_MP4_ADTS: case TT_MP4_ADTS:
@ -425,22 +424,7 @@ static void FDKaacEnc_MapConfig(
cc->flags = 0; cc->flags = 0;
/* Map virtual aot to transport aot. */ transport_AOT = hAacConfig->audioObjectType;
switch (hAacConfig->audioObjectType) {
case AOT_MP2_AAC_LC:
transport_AOT = AOT_AAC_LC;
break;
case AOT_MP2_SBR:
transport_AOT = AOT_SBR;
cc->flags |= CC_SBR;
break;
case AOT_MP2_PS:
transport_AOT = AOT_PS;
cc->flags |= CC_SBR;
break;
default:
transport_AOT = hAacConfig->audioObjectType;
}
if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0; cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
@ -506,16 +490,7 @@ static void FDKaacEnc_MapConfig(
cc->samplingRate = hAacConfig->sampleRate; cc->samplingRate = hAacConfig->sampleRate;
/* Mpeg-4 signaling for transport library. */ /* Mpeg-4 signaling for transport library. */
switch ( hAacConfig->audioObjectType ) { cc->flags |= CC_MPEG_ID;
case AOT_MP2_AAC_LC:
case AOT_MP2_SBR:
case AOT_MP2_PS:
cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
cc->extAOT = AOT_NULL_OBJECT;
break;
default:
cc->flags |= CC_MPEG_ID;
}
/* ER-tools signaling. */ /* ER-tools signaling. */
cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0; cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
@ -580,6 +555,7 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
config->userChannelMode = hAacConfig->channelMode; config->userChannelMode = hAacConfig->channelMode;
config->userBitrate = hAacConfig->bitRate; config->userBitrate = hAacConfig->bitRate;
config->userBitrateMode = hAacConfig->bitrateMode; config->userBitrateMode = hAacConfig->bitrateMode;
config->userPeakBitrate = (UINT)-1;
config->userBandwidth = hAacConfig->bandWidth; config->userBandwidth = hAacConfig->bandWidth;
config->userTns = hAacConfig->useTns; config->userTns = hAacConfig->useTns;
config->userPns = hAacConfig->usePns; config->userPns = hAacConfig->usePns;
@ -787,12 +763,15 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
hAacConfig->syntaxFlags = 0; hAacConfig->syntaxFlags = 0;
hAacConfig->epConfig = -1; hAacConfig->epConfig = -1;
if (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) {
hAacConfig->audioMuxVersion = config->userTpAmxv;
}
else {
hAacConfig->audioMuxVersion = -1;
}
/* Adapt internal AOT when necessary. */ /* Adapt internal AOT when necessary. */
switch ( hAacConfig->audioObjectType ) { switch ( hAacConfig->audioObjectType ) {
case AOT_MP2_AAC_LC:
case AOT_MP2_SBR:
case AOT_MP2_PS:
hAacConfig->usePns = 0;
case AOT_AAC_LC: case AOT_AAC_LC:
case AOT_SBR: case AOT_SBR:
case AOT_PS: case AOT_PS:
@ -834,11 +813,16 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
switch ( hAacConfig->audioObjectType ) { switch ( hAacConfig->audioObjectType ) {
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
if (config->userBitrateMode==8) {
hAacConfig->bitrateMode = 0;
}
if (config->userBitrateMode==0) { if (config->userBitrateMode==0) {
hAacConfig->bitreservoir = 100*config->nChannels; /* default, reduced bitreservoir */ /* bitreservoir = (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; */
if ( isLowDelay(hAacConfig->audioObjectType) ) {
INT bitreservoir;
INT brPerChannel = hAacConfig->bitRate/hAacConfig->nChannels;
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
FIXP_DBL slope = fDivNorm((brPerChannel-BITRATE_MIN_LD), BITRATE_MAX_LD-BITRATE_MIN_LD); /* calc slope for interpolation */
bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD-BITRES_MIN_LD)) + BITRES_MIN_LD; /* interpolate */
hAacConfig->bitreservoir = bitreservoir & ~7; /* align to bytes */
}
} }
if (hAacConfig->bitrateMode!=0) { if (hAacConfig->bitrateMode!=0) {
return AACENC_INVALID_CONFIG; return AACENC_INVALID_CONFIG;
@ -879,6 +863,18 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
} }
} }
if ((hAacConfig->bitrateMode >= 0) && (hAacConfig->bitrateMode <= 5)) {
if ((INT)config->userPeakBitrate != -1) {
hAacConfig->maxBitsPerFrame = (FDKaacEnc_CalcBitsPerFrame(fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), hAacConfig->framelength, hAacConfig->sampleRate) + 7)&~7;
}
else {
hAacConfig->maxBitsPerFrame = -1;
}
if (hAacConfig->audioMuxVersion==2) {
hAacConfig->minBitsPerFrame = fMin(32*8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, hAacConfig->framelength, hAacConfig->sampleRate))&~7;
}
}
/* Initialize SBR parameters */ /* Initialize SBR parameters */
if ( (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) if ( (hAacConfig->audioObjectType==AOT_ER_AAC_ELD)
&& (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio==0) ) && (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio==0) )
@ -909,7 +905,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
} }
else { else {
/* SBR ratio has been set by the user, so use it. */ /* SBR ratio has been set by the user, so use it. */
hAacConfig->sbrRatio = config->userSbrRatio; hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0;
} }
{ {
@ -1041,7 +1037,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
} }
/* Clear input buffer */ /* Clear input buffer */
if ( (InitFlags == AACENC_INIT_ALL) ) { if ( InitFlags == AACENC_INIT_ALL ) {
FDKmemclear(hAacEncoder->inputBuffer, sizeof(INT_PCM)*hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE); FDKmemclear(hAacEncoder->inputBuffer, sizeof(INT_PCM)*hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE);
} }
@ -1134,7 +1130,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
hAacConfig); hAacConfig);
/* create flags for transport encoder */ /* create flags for transport encoder */
if (config->userTpAmxv == 1) { if (config->userTpAmxv != 0) {
flags |= TP_FLAG_LATM_AMV; flags |= TP_FLAG_LATM_AMV;
} }
/* Clear output buffer */ /* Clear output buffer */
@ -1564,7 +1560,7 @@ AACENC_ERROR aacEncEncode(
&& ((hAacEncoder->extParam.userChannelMode==MODE_1_2_2)||(hAacEncoder->extParam.userChannelMode==MODE_1_2_2_1)) ) && ((hAacEncoder->extParam.userChannelMode==MODE_1_2_2)||(hAacEncoder->extParam.userChannelMode==MODE_1_2_2_1)) )
{ {
/* Set matrix mixdown coefficient. */ /* Set matrix mixdown coefficient. */
UINT pceValue = (UINT)( (1<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 ); UINT pceValue = (UINT)( (0<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 );
if (hAacEncoder->extParam.userPceAdditions != pceValue) { if (hAacEncoder->extParam.userPceAdditions != pceValue) {
hAacEncoder->extParam.userPceAdditions = pceValue; hAacEncoder->extParam.userPceAdditions = pceValue;
hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
@ -1780,19 +1776,16 @@ AACENC_ERROR aacEncoder_SetParam(
/* check if AOT matches the allocated modules */ /* check if AOT matches the allocated modules */
switch ( value ) { switch ( value ) {
case AOT_PS: case AOT_PS:
case AOT_MP2_PS:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) { if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
err = AACENC_INVALID_CONFIG; err = AACENC_INVALID_CONFIG;
goto bail; goto bail;
} }
case AOT_SBR: case AOT_SBR:
case AOT_MP2_SBR:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) { if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
err = AACENC_INVALID_CONFIG; err = AACENC_INVALID_CONFIG;
goto bail; goto bail;
} }
case AOT_AAC_LC: case AOT_AAC_LC:
case AOT_MP2_AAC_LC:
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
@ -1818,11 +1811,7 @@ AACENC_ERROR aacEncoder_SetParam(
if (settings->userBitrateMode != value) { if (settings->userBitrateMode != value) {
switch ( value ) { switch ( value ) {
case 0: case 0:
case 1: case 1: case 2: case 3: case 4: case 5:
case 2:
case 3:
case 4:
case 5:
case 8: case 8:
settings->userBitrateMode = value; settings->userBitrateMode = value;
hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
@ -1973,6 +1962,16 @@ AACENC_ERROR aacEncoder_SetParam(
hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
} }
break; break;
case AACENC_AUDIOMUXVER:
if (settings->userTpAmxv != value) {
if ( !((value==0) || (value==1) || (value==2)) ) {
err = AACENC_INVALID_CONFIG;
break;
}
settings->userTpAmxv = value;
hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
}
break;
case AACENC_TPSUBFRAMES: case AACENC_TPSUBFRAMES:
if (settings->userTpNsubFrames != value) { if (settings->userTpNsubFrames != value) {
if (! ( (value>=1) && (value<=4) ) ) { if (! ( (value>=1) && (value<=4) ) ) {
@ -1998,7 +1997,7 @@ AACENC_ERROR aacEncoder_SetParam(
break; break;
case AACENC_METADATA_MODE: case AACENC_METADATA_MODE:
if ((UINT)settings->userMetaDataMode != value) { if ((UINT)settings->userMetaDataMode != value) {
if ( !((value>=0) && (value<=2)) ) { if ( !(((INT)value>=0) && ((INT)value<=2)) ) {
err = AACENC_INVALID_CONFIG; err = AACENC_INVALID_CONFIG;
break; break;
} }
@ -2006,6 +2005,12 @@ AACENC_ERROR aacEncoder_SetParam(
hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
} }
break; break;
case AACENC_PEAK_BITRATE:
if (settings->userPeakBitrate != value) {
settings->userPeakBitrate = value;
hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
}
break;
default: default:
err = AACENC_UNSUPPORTED_PARAMETER; err = AACENC_UNSUPPORTED_PARAMETER;
break; break;
@ -2076,6 +2081,9 @@ UINT aacEncoder_GetParam(
case AACENC_HEADER_PERIOD: case AACENC_HEADER_PERIOD:
value = (UINT)hAacEncoder->coderConfig.headerPeriod; value = (UINT)hAacEncoder->coderConfig.headerPeriod;
break; break;
case AACENC_AUDIOMUXVER:
value = (UINT)hAacEncoder->aacConfig.audioMuxVersion;
break;
case AACENC_TPSUBFRAMES: case AACENC_TPSUBFRAMES:
value = (UINT)settings->userTpNsubFrames; value = (UINT)settings->userTpNsubFrames;
break; break;
@ -2088,6 +2096,12 @@ UINT aacEncoder_GetParam(
case AACENC_METADATA_MODE: case AACENC_METADATA_MODE:
value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode; value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode;
break; break;
case AACENC_PEAK_BITRATE:
value = (UINT)-1; /* peak bitrate parameter is meaningless */
if ( ((INT)hAacEncoder->extParam.userPeakBitrate!=-1) ) {
value = (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, hAacEncoder->aacConfig.bitRate)); /* peak bitrate parameter is in use */
}
break;
default: default:
//err = MPS_INVALID_PARAMETER; //err = MPS_INVALID_PARAMETER;
break; break;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -95,13 +95,7 @@ amm-info@iis.fraunhofer.de
#include "aacEnc_rom.h" #include "aacEnc_rom.h"
#include "aacenc_tns.h" #include "aacenc_tns.h"
enum { #define FILTER_DIRECTION 0 /* 0 = up, 1 = down */
HIFILT = 0, /* index of higher filter */
LOFILT = 1 /* index of lower filter */
};
#define FILTER_DIRECTION 0
static const FIXP_DBL acfWindowLong[12+3+1] = { static const FIXP_DBL acfWindowLong[12+3+1] = {
0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000, 0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000,
@ -112,20 +106,6 @@ static const FIXP_DBL acfWindowShort[4+3+1] = {
0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000 0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000
}; };
typedef struct {
INT filterEnabled[MAX_NUM_OF_FILTERS];
INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
INT acfSplit[MAX_NUM_OF_FILTERS];
FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */
INT seperateFiltersAllowed;
} TNS_PARAMETER_TABULATED;
typedef struct{ typedef struct{
INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */ INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */
INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */ INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */
@ -373,6 +353,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
INT channels, INT channels,
INT blockType, INT blockType,
INT granuleLength, INT granuleLength,
INT isLowDelay,
INT ldSbrPresent, INT ldSbrPresent,
TNS_CONFIG *tC, TNS_CONFIG *tC,
PSY_CONFIGURATION *pC, PSY_CONFIGURATION *pC,
@ -385,6 +366,8 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
if (channels <= 0) if (channels <= 0)
return (AAC_ENCODER_ERROR)1; return (AAC_ENCODER_ERROR)1;
tC->isLowDelay = isLowDelay;
/* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */ /* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */
tC->tnsActive = (active) ? TRUE : FALSE; tC->tnsActive = (active) ? TRUE : FALSE;
tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */ tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */
@ -450,27 +433,14 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent); const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);
if ( pCfg != NULL ) { if ( pCfg != NULL ) {
FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab));
tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]]; tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]];
tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
tC->confTab.threshOn[HIFILT] = pCfg->threshOn[HIFILT];
tC->confTab.threshOn[LOFILT] = pCfg->threshOn[LOFILT];
tC->confTab.tnsLimitOrder[HIFILT] = pCfg->tnsLimitOrder[HIFILT];
tC->confTab.tnsLimitOrder[LOFILT] = pCfg->tnsLimitOrder[LOFILT];
tC->confTab.tnsFilterDirection[HIFILT] = pCfg->tnsFilterDirection[HIFILT];
tC->confTab.tnsFilterDirection[LOFILT] = pCfg->tnsFilterDirection[LOFILT];
tC->confTab.acfSplit[HIFILT] = pCfg->acfSplit[HIFILT];
tC->confTab.acfSplit[LOFILT] = pCfg->acfSplit[LOFILT];
tC->confTab.filterEnabled[HIFILT] = pCfg->filterEnabled[HIFILT];
tC->confTab.filterEnabled[LOFILT] = pCfg->filterEnabled[LOFILT];
tC->confTab.seperateFiltersAllowed = pCfg->seperateFiltersAllowed;
FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE); FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE);
FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE); FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE);
} }
@ -614,6 +584,7 @@ static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(
static void FDKaacEnc_MergedAutoCorrelation( static void FDKaacEnc_MergedAutoCorrelation(
const FIXP_DBL *spectrum, const FIXP_DBL *spectrum,
const INT isLowDelay,
const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1], const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1],
const INT lpcStartLine[MAX_NUM_OF_FILTERS], const INT lpcStartLine[MAX_NUM_OF_FILTERS],
const INT lpcStopLine, const INT lpcStopLine,
@ -633,6 +604,8 @@ static void FDKaacEnc_MergedAutoCorrelation(
FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1)); FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1));
FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1)); FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1));
idx0 = idx1 = idx2 = idx3 = idx4 = 0;
/* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */ /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */
if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) { if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) {
/* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */ /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */
@ -676,17 +649,27 @@ static void FDKaacEnc_MergedAutoCorrelation(
/* compute energy normalization factors, i. e. 1/energy (saves some divisions) */ /* compute energy normalization factors, i. e. 1/energy (saves some divisions) */
if (rxx1_0 != FL2FXCONST_DBL(0.f)) if (rxx1_0 != FL2FXCONST_DBL(0.f))
{ {
INT sc_fac1 = -1; INT sc_fac1 = -1;
FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1); FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1);
_rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1); _rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1);
if (isLowDelay)
{
for (lag = 1; lag <= maxOrder; lag++) { for (lag = 1; lag <= maxOrder; lag++) {
/* compute energy-normalized and windowed autocorrelation values at this lag */ /* compute energy-normalized and windowed autocorrelation values at this lag */
FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
_rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][lag]);
}
}
else
{
for (lag = 1; lag <= maxOrder; lag++) {
if ((3 * lag) <= maxOrder + 3) { if ((3 * lag) <= maxOrder + 3) {
FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
_rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][3*lag]); _rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][3*lag]);
} }
} }
}
} }
/* auto corr over upper 3/4 of spectrum */ /* auto corr over upper 3/4 of spectrum */
@ -762,8 +745,12 @@ INT FDKaacEnc_TnsDetect(
: &tnsData->dataRaw.Long.subBlockInfo; : &tnsData->dataRaw.Long.subBlockInfo;
tnsData->filtersMerged = FALSE; tnsData->filtersMerged = FALSE;
tsbi->tnsActive = FALSE;
tsbi->predictionGain = 1000; tsbi->tnsActive[HIFILT] = FALSE;
tsbi->predictionGain[HIFILT] = 1000;
tsbi->tnsActive[LOFILT] = FALSE;
tsbi->predictionGain[LOFILT] = 1000;
tnsInfo->numOfFilters[subBlockNumber] = 0; tnsInfo->numOfFilters[subBlockNumber] = 0;
tnsInfo->coefRes[subBlockNumber] = tC->coefRes; tnsInfo->coefRes[subBlockNumber] = tC->coefRes;
for (i = 0; i < tC->maxOrder; i++) { for (i = 0; i < tC->maxOrder; i++) {
@ -779,6 +766,7 @@ INT FDKaacEnc_TnsDetect(
FDKaacEnc_MergedAutoCorrelation( FDKaacEnc_MergedAutoCorrelation(
spectrum, spectrum,
tC->isLowDelay,
tC->acfWindow, tC->acfWindow,
tC->lpcStartLine, tC->lpcStartLine,
tC->lpcStopLine, tC->lpcStopLine,
@ -788,7 +776,7 @@ INT FDKaacEnc_TnsDetect(
rxx2); rxx2);
/* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ /* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */
tsbi->predictionGain = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]); tsbi->predictionGain[HIFILT] = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]);
/* non-linear quantization of TNS lattice coefficients with given resolution */ /* non-linear quantization of TNS lattice coefficients with given resolution */
FDKaacEnc_Parcor2Index( FDKaacEnc_Parcor2Index(
@ -815,9 +803,9 @@ INT FDKaacEnc_TnsDetect(
tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT]; tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT];
/* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */ /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */
if ((tsbi->predictionGain > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2))) if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2)))
{ {
tsbi->tnsActive = TRUE; tsbi->tnsActive[HIFILT] = TRUE;
tnsInfo->numOfFilters[subBlockNumber]++; tnsInfo->numOfFilters[subBlockNumber]++;
/* compute second filter for lower quarter; only allowed for long windows! */ /* compute second filter for lower quarter; only allowed for long windows! */
@ -857,6 +845,7 @@ INT FDKaacEnc_TnsDetect(
|| ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) ) || ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) )
{ {
/* compare lower to upper filter; if they are very similar, merge them */ /* compare lower to upper filter; if they are very similar, merge them */
tsbi->tnsActive[LOFILT] = TRUE;
sumSqrCoef = 0; sumSqrCoef = 0;
for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) { for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) {
sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]); sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]);
@ -884,6 +873,8 @@ INT FDKaacEnc_TnsDetect(
tnsInfo->numOfFilters[subBlockNumber]++; tnsInfo->numOfFilters[subBlockNumber]++;
} }
} /* filter lower part */ } /* filter lower part */
tsbi->predictionGain[LOFILT]=predGain;
} /* second filter allowed */ } /* second filter allowed */
} /* if predictionGain > 1437 ... */ } /* if predictionGain > 1437 ... */
} /* maxOrder > 0 && tnsActive */ } /* maxOrder > 0 && tnsActive */
@ -944,7 +935,7 @@ void FDKaacEnc_TnsSync(
INT doSync = 1, absDiffSum = 0; INT doSync = 1, absDiffSum = 0;
/* if TNS is active in at least one channel, check if ParCor coefficients of higher filter are similar */ /* if TNS is active in at least one channel, check if ParCor coefficients of higher filter are similar */
if (pSbInfoDestW->tnsActive || pSbInfoSrcW->tnsActive) { if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) {
for (i = 0; i < tC->maxOrder; i++) { for (i = 0; i < tC->maxOrder; i++) {
absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]); absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]);
absDiffSum += absDiff; absDiffSum += absDiff;
@ -957,12 +948,12 @@ void FDKaacEnc_TnsSync(
if (doSync) { if (doSync) {
/* if no significant difference was detected, synchronize coefficient sets */ /* if no significant difference was detected, synchronize coefficient sets */
if (pSbInfoSrcW->tnsActive) { if (pSbInfoSrcW->tnsActive[HIFILT]) {
/* no dest filter, or more dest than source filters: use one dest filter */ /* no dest filter, or more dest than source filters: use one dest filter */
if ((!pSbInfoDestW->tnsActive) || if ((!pSbInfoDestW->tnsActive[HIFILT]) ||
((pSbInfoDestW->tnsActive) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) ((pSbInfoDestW->tnsActive[HIFILT]) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w])))
{ {
pSbInfoDestW->tnsActive = tnsInfoDest->numOfFilters[w] = 1; pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1;
} }
tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged; tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged;
tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT]; tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT];
@ -975,7 +966,7 @@ void FDKaacEnc_TnsSync(
} }
} }
else else
pSbInfoDestW->tnsActive = tnsInfoDest->numOfFilters[w] = 0; pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0;
} }
} }
@ -1012,8 +1003,8 @@ INT FDKaacEnc_TnsEncode(
{ {
INT i, startLine, stopLine; INT i, startLine, stopLine;
if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive) ) if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive[HIFILT]) )
|| ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive) ) ) || ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]) ) )
{ {
return 1; return 1;
} }
@ -1129,8 +1120,9 @@ static INT FDKaacEnc_AutoToParcor(
FIXP_DBL *RESTRICT workBuffer = parcorWorkBuffer; FIXP_DBL *RESTRICT workBuffer = parcorWorkBuffer;
const FIXP_DBL autoCorr_0 = input[0]; const FIXP_DBL autoCorr_0 = input[0];
FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL));
if((FIXP_DBL)input[0] == FL2FXCONST_DBL(0.0)) { if((FIXP_DBL)input[0] == FL2FXCONST_DBL(0.0)) {
FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL));
return(predictionGain); return(predictionGain);
} }

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -117,21 +117,25 @@ amm-info@iis.fraunhofer.de
#define MAX_NUM_OF_FILTERS 2 #define MAX_NUM_OF_FILTERS 2
#define HIFILT 0 /* index of higher filter */
#define LOFILT 1 /* index of lower filter */
typedef struct{ /*stuff that is tabulated dependent on bitrate etc. */
INT filterEnabled[MAX_NUM_OF_FILTERS];
INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
INT acfSplit[MAX_NUM_OF_FILTERS];
INT seperateFiltersAllowed;
}TNS_CONFIG_TABULATED;
typedef struct{ /* stuff that is tabulated dependent on bitrate etc. */
INT filterEnabled[MAX_NUM_OF_FILTERS];
INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
INT acfSplit[MAX_NUM_OF_FILTERS];
FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */
INT seperateFiltersAllowed;
} TNS_PARAMETER_TABULATED;
typedef struct { /*assigned at InitTime*/ typedef struct { /*assigned at InitTime*/
TNS_CONFIG_TABULATED confTab; TNS_PARAMETER_TABULATED confTab;
INT isLowDelay;
INT tnsActive; INT tnsActive;
INT maxOrder; /* max. order of tns filter */ INT maxOrder; /* max. order of tns filter */
INT coefRes; INT coefRes;
@ -148,8 +152,8 @@ typedef struct { /*assigned at InitTime*/
typedef struct { typedef struct {
INT tnsActive; INT tnsActive[MAX_NUM_OF_FILTERS];
INT predictionGain; INT predictionGain[MAX_NUM_OF_FILTERS];
} TNS_SUBBLOCK_INFO; } TNS_SUBBLOCK_INFO;
typedef struct{ /*changed at runTime*/ typedef struct{ /*changed at runTime*/

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -130,14 +130,14 @@ the crash recovery strategy will be activated once.
typedef struct { typedef struct {
INT bitrate; INT bitrate;
LONG bits2PeFactor_mono; ULONG bits2PeFactor_mono;
LONG bits2PeFactor_mono_slope; ULONG bits2PeFactor_mono_slope;
LONG bits2PeFactor_stereo; ULONG bits2PeFactor_stereo;
LONG bits2PeFactor_stereo_slope; ULONG bits2PeFactor_stereo_slope;
LONG bits2PeFactor_mono_scfOpt; ULONG bits2PeFactor_mono_scfOpt;
LONG bits2PeFactor_mono_scfOpt_slope; ULONG bits2PeFactor_mono_scfOpt_slope;
LONG bits2PeFactor_stereo_scfOpt; ULONG bits2PeFactor_stereo_scfOpt;
LONG bits2PeFactor_stereo_scfOpt_slope; ULONG bits2PeFactor_stereo_scfOpt_slope;
} BIT_PE_SFAC; } BIT_PE_SFAC;
@ -153,10 +153,10 @@ static const BIT_PE_SFAC S_Bits2PeTab16000[] = {
{ 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413}, { 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413},
{ 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105}, { 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105},
{ 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105}, { 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105},
{ 64000, 0x60000000, 0x00000000, 0x251EB852, 0x154C985F, 0x60000000, 0x00000000, 0x2570A3D7, 0x154C985F}, { 64000, 0x25c28f40, 0x00000000, 0x251EB852, 0x01480000, 0x25c28f40, 0x00000000, 0x2570A3D7, 0x01480000},
{ 96000, 0x60000000, 0x00000000, 0x39EB851F, 0x088509C0, 0x60000000, 0x00000000, 0x3A3D70A4, 0x088509C0}, { 96000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000},
{128000, 0x60000000, 0x00000000, 0x423D70A4, 0x18A43BB4, 0x60000000, 0x00000000, 0x428F5C29, 0x181E03F7}, {128000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000},
{148000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000} {148000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000}
}; };
static const BIT_PE_SFAC S_Bits2PeTab22050[] = { static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
@ -166,8 +166,8 @@ static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
{ 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a}, { 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a},
{ 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882}, { 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882},
{ 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882}, { 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882},
{128000, 0x60000000, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x00000000, 0x2570a3d7, 0x009f16b1}, {128000, 0x25c28f40, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x25c28f40, 0x2570a3d7, 0x009f16b1},
{148000, 0x60000000, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x00000000, 0x270a3d71, 0x00000000} {148000, 0x25c28f40, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x25c28f40, 0x270a3d71, 0x00000000}
}; };
static const BIT_PE_SFAC S_Bits2PeTab24000[] = { static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
@ -178,21 +178,21 @@ static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
{ 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59}, { 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59},
{ 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882}, { 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882},
{128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a}, {128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a},
{148000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000} {148000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000}
}; };
static const BIT_PE_SFAC S_Bits2PeTab32000[] = { static const BIT_PE_SFAC S_Bits2PeTab32000[] = {
{ 16000, 0x1199999a, 0x20c49ba6, 0x00000000, 0x4577d955, 0x00000000, 0x60fe4799, 0x00000000, 0x00000000}, { 16000, 0x247ae140, 0xFFFFAC1E, 0x270a3d80, 0xFFFE9B7C, 0x14ccccc0, 0x000110A1, 0x15c28f60, 0xFFFEEF5F},
{ 24000, 0x1999999a, 0x0fba8827, 0x10f5c28f, 0x1b866e44, 0x17ae147b, 0x0fba8827, 0x00000000, 0x4d551d69}, { 24000, 0x23333340, 0x0fba8827, 0x21999980, 0x1b866e44, 0x18f5c280, 0x0fba8827, 0x119999a0, 0x4d551d69},
{ 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f}, { 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f},
{ 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e}, { 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e},
{ 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a}, { 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a},
{ 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f}, { 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f},
{128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737}, {128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737},
{148000, 0x60000000, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476}, {148000, 0x25c28f40, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476},
{160000, 0x60000000, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184}, {160000, 0x25c28f40, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184},
{200000, 0x00000000, 0x00000000, 0x2b333333, 0x0836be91, 0x00000000, 0x00000000, 0x2b333333, 0x0890390f}, {200000, 0x25c28f40, 0x00000000, 0x2b333333, 0x0836be91, 0x25c28f40, 0x00000000, 0x2b333333, 0x0890390f},
{320000, 0x00000000, 0x00000000, 0x4947ae14, 0x00000000, 0x00000000, 0x00000000, 0x4a8f5c29, 0x00000000} {320000, 0x25c28f40, 0x00000000, 0x4947ae14, 0x00000000, 0x25c28f40, 0x00000000, 0x4a8f5c29, 0x00000000}
}; };
static const BIT_PE_SFAC S_Bits2PeTab44100[] = { static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
@ -205,8 +205,8 @@ static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
{128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737}, {128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737},
{148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b}, {148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b},
{160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316}, {160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316},
{200000, 0x00000000, 0x00000000, 0x25c28f5c, 0x0713f078, 0x00000000, 0x00000000, 0x2570a3d7, 0x072a4f17}, {200000, 0x25c28f40, 0x00000000, 0x25c28f5c, 0x0713f078, 0x25c28f40, 0x00000000, 0x2570a3d7, 0x072a4f17},
{320000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000} {320000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000}
}; };
static const BIT_PE_SFAC S_Bits2PeTab48000[] = { static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
@ -219,8 +219,8 @@ static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
{128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4}, {128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4},
{148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476}, {148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476},
{160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737}, {160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737},
{200000, 0x00000000, 0x00000000, 0x251eb852, 0x06775a1b, 0x00000000, 0x00000000, 0x24cccccd, 0x06a4175a}, {200000, 0x25c28f40, 0x00000000, 0x251eb852, 0x06775a1b, 0x25c28f40, 0x00000000, 0x24cccccd, 0x06a4175a},
{320000, 0x00000000, 0x00000000, 0x3ccccccd, 0x00000000, 0x00000000, 0x00000000, 0x3d1eb852, 0x00000000} {320000, 0x25c28f40, 0x00000000, 0x3ccccccd, 0x00000000, 0x25c28f40, 0x00000000, 0x3d1eb852, 0x00000000}
}; };
static const BITS2PE_CFG_TAB bits2PeConfigTab[] = { static const BITS2PE_CFG_TAB bits2PeConfigTab[] = {
@ -258,6 +258,7 @@ static void FDKaacEnc_InitBits2PeFactor(
const INT nChannels, const INT nChannels,
const INT sampleRate, const INT sampleRate,
const INT advancedBitsToPe, const INT advancedBitsToPe,
const INT dZoneQuantEnable,
const INT invQuant const INT invQuant
) )
{ {
@ -329,7 +330,32 @@ static void FDKaacEnc_InitBits2PeFactor(
} /* advancedBitsToPe */ } /* advancedBitsToPe */
/* return bits2pe factor */ if (dZoneQuantEnable)
{
if(bit2PE_m >= (FL2FXCONST_DBL(0.6f))>>bit2PE_e)
{
/* Additional headroom for addition */
bit2PE_m >>= 1;
bit2PE_e += 1;
}
/* the quantTendencyCompensator compensates a lower bit consumption due to increasing the tendency to quantize low spectral values to the lower quantizer border for bitrates below a certain bitrate threshold --> see also function calcSfbDistLD in quantize.c */
if ((bitRate/nChannels > 32000) && (bitRate/nChannels <= 40000)) {
bit2PE_m += (FL2FXCONST_DBL(0.4f))>>bit2PE_e;
}
else if (bitRate/nChannels > 20000) {
bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e;
}
else if (bitRate/nChannels >= 16000) {
bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e;
}
else {
bit2PE_m += (FL2FXCONST_DBL(0.0f))>>bit2PE_e;
}
}
/***** 3.) Return bits2pe factor *****/
*bits2PeFactor_m = bit2PE_m; *bits2PeFactor_m = bit2PE_m;
*bits2PeFactor_e = bit2PE_e; *bits2PeFactor_e = bit2PE_e;
} }
@ -1649,6 +1675,7 @@ static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm,
QC_OUT_ELEMENT* qcElement[(8)], QC_OUT_ELEMENT* qcElement[(8)],
PSY_OUT_ELEMENT* psyOutElement[(8)], PSY_OUT_ELEMENT* psyOutElement[(8)],
const INT desiredPe, const INT desiredPe,
const INT maxIter2ndGuess,
const INT processElements, const INT processElements,
const INT elementOffset) const INT elementOffset)
{ {
@ -1733,7 +1760,7 @@ static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm,
/* Part III: Iterate until bit constraints are met */ /* Part III: Iterate until bit constraints are met */
/* -------------------------------------------------- */ /* -------------------------------------------------- */
iter = 0; iter = 0;
while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < 1)) { while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < maxIter2ndGuess)) {
INT desiredPeNoAHGlobal; INT desiredPeNoAHGlobal;
INT redPeNoAHGlobal = 0; INT redPeNoAHGlobal = 0;
@ -2138,7 +2165,7 @@ static FIXP_DBL FDKaacEnc_bitresCalcBitFac(const INT bitresBits,
bresParam->clipSpendLow, bresParam->clipSpendHigh, bresParam->clipSpendLow, bresParam->clipSpendHigh,
bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope);
pe_pers = fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin); pe_pers = (pex > adjThrChan->peMin) ? fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin) : 0;
tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers); tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers);
bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2); bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2);
@ -2225,7 +2252,8 @@ void FDKaacEnc_AdjThrInit(
INT nChannelsEff, INT nChannelsEff,
INT sampleRate, INT sampleRate,
INT advancedBitsToPe, INT advancedBitsToPe,
FIXP_DBL vbrQualFactor FIXP_DBL vbrQualFactor,
const INT dZoneQuantEnable
) )
{ {
INT i; INT i;
@ -2233,6 +2261,10 @@ void FDKaacEnc_AdjThrInit(
FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f); FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f);
FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f); FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f);
/* Max number of iterations in second guess is 3 for lowdelay aot and for configurations with
multiple audio elements in general, otherwise iteration value is always 1. */
hAdjThr->maxIter2ndGuess = (advancedBitsToPe!=0 || nElements>1) ? 3 : 1;
/* common for all elements: */ /* common for all elements: */
/* parameters for bitres control */ /* parameters for bitres control */
hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
@ -2313,10 +2345,11 @@ void FDKaacEnc_AdjThrInit(
FDKaacEnc_InitBits2PeFactor( FDKaacEnc_InitBits2PeFactor(
&atsElem->bits2PeFactor_m, &atsElem->bits2PeFactor_m,
&atsElem->bits2PeFactor_e, &atsElem->bits2PeFactor_e,
chBitrate, /* bitrate/channel*/ chBitrate*nChannelsEff, /* overall bitrate */
nChannelsEff, /* number of channels */ nChannelsEff, /* number of channels */
sampleRate, sampleRate,
advancedBitsToPe, advancedBitsToPe,
dZoneQuantEnable,
invQuant invQuant
); );
@ -2545,6 +2578,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
QC_OUT* qcOut, QC_OUT* qcOut,
PSY_OUT_ELEMENT* psyOutElement[(8)], PSY_OUT_ELEMENT* psyOutElement[(8)],
INT CBRbitrateMode, INT CBRbitrateMode,
INT maxIter2ndGuess,
CHANNEL_MAPPING* cm) CHANNEL_MAPPING* cm)
{ {
int i; int i;
@ -2570,6 +2604,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
qcElement, qcElement,
psyOutElement, psyOutElement,
qcElement[i]->grantedPeCorr, qcElement[i]->grantedPeCorr,
maxIter2ndGuess,
1, /* Process only 1 element */ 1, /* Process only 1 element */
i); /* Process exactly THIS element */ i); /* Process exactly THIS element */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -118,7 +118,8 @@ void FDKaacEnc_AdjThrInit(ADJ_THR_STATE *hAdjThr,
INT nChannelsEff, INT nChannelsEff,
INT sampleRate, INT sampleRate,
INT advancedBitsToPe, INT advancedBitsToPe,
FIXP_DBL vbrQualFactor); FIXP_DBL vbrQualFactor,
const INT dZoneQuantEnable);
void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState, void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState,
@ -140,6 +141,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
QC_OUT* qcOut, QC_OUT* qcOut,
PSY_OUT_ELEMENT* psyOutElement[(8)], PSY_OUT_ELEMENT* psyOutElement[(8)],
INT CBRbitrateMode, INT CBRbitrateMode,
INT maxIter2ndGuess,
CHANNEL_MAPPING* cm); CHANNEL_MAPPING* cm);
void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** hAdjThr); void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** hAdjThr);

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -145,6 +145,7 @@ typedef struct {
typedef struct { typedef struct {
BRES_PARAM bresParamLong, bresParamShort; BRES_PARAM bresParamLong, bresParamShort;
ATS_ELEMENT* adjThrStateElem[(8)]; ATS_ELEMENT* adjThrStateElem[(8)];
INT maxIter2ndGuess;
} ADJ_THR_STATE; } ADJ_THR_STATE;
#endif #endif

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -127,7 +127,7 @@ static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
{ 8000, 2000, 2000}, { 8000, 2000, 2000},
{12000, 2000, 2300}, {12000, 2000, 2300},
{16000, 2200, 2500}, {16000, 2200, 2500},
{24000, 5650, 6400}, {24000, 5650, 7200},
{32000, 11600, 12000}, {32000, 11600, 12000},
{40000, 12000, 16000}, {40000, 12000, 16000},
{48000, 16000, 16000}, {48000, 16000, 16000},
@ -138,10 +138,10 @@ static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = { static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = {
{ 8000, 2000, 2000}, { 8000, 2000, 2000},
{12000, 2000, 2000}, {12000, 2000, 2000},
{24000, 4250, 5200}, {24000, 4250, 7200},
{32000, 8400, 9000}, {32000, 8400, 9000},
{40000, 9400, 11300}, {40000, 9400, 11300},
{48000, 11900, 13700}, {48000, 11900, 14700},
{64000, 14800, 16000}, {64000, 14800, 16000},
{76000, 16000, 16000}, {76000, 16000, 16000},
{360001, 16000, 16000} {360001, 16000, 16000}

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2014 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION

View File

@ -193,36 +193,36 @@ struct DRC_COMP {
* Profile tables. * Profile tables.
*/ */
static const FIXP_DBL tabMaxBoostThr[] = { static const FIXP_DBL tabMaxBoostThr[] = {
(FIXP_DBL)(-43<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-43<<METADATA_FRACT_BITS),
(FIXP_DBL)(-53<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-53<<METADATA_FRACT_BITS),
(FIXP_DBL)(-55<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-55<<METADATA_FRACT_BITS),
(FIXP_DBL)(-65<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-65<<METADATA_FRACT_BITS),
(FIXP_DBL)(-50<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-50<<METADATA_FRACT_BITS),
(FIXP_DBL)(-40<<METADATA_FRACT_BITS) (FIXP_DBL)(int)((unsigned)-40<<METADATA_FRACT_BITS)
}; };
static const FIXP_DBL tabBoostThr[] = { static const FIXP_DBL tabBoostThr[] = {
(FIXP_DBL)(-31<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS),
(FIXP_DBL)(-41<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-41<<METADATA_FRACT_BITS),
(FIXP_DBL)(-31<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS),
(FIXP_DBL)(-41<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-41<<METADATA_FRACT_BITS),
(FIXP_DBL)(-31<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS),
(FIXP_DBL)(-31<<METADATA_FRACT_BITS) (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS)
}; };
static const FIXP_DBL tabEarlyCutThr[] = { static const FIXP_DBL tabEarlyCutThr[] = {
(FIXP_DBL)(-26<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS),
(FIXP_DBL)(-21<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS),
(FIXP_DBL)(-26<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS),
(FIXP_DBL)(-21<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS),
(FIXP_DBL)(-26<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS),
(FIXP_DBL)(-20<<METADATA_FRACT_BITS) (FIXP_DBL)(int)((unsigned)-20<<METADATA_FRACT_BITS)
}; };
static const FIXP_DBL tabCutThr[] = { static const FIXP_DBL tabCutThr[] = {
(FIXP_DBL)(-16<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS),
(FIXP_DBL)(-11<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-11<<METADATA_FRACT_BITS),
(FIXP_DBL)(-16<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS),
(FIXP_DBL)(-21<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS),
(FIXP_DBL)(-16<<METADATA_FRACT_BITS), (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS),
(FIXP_DBL)(-10<<METADATA_FRACT_BITS) (FIXP_DBL)(int)((unsigned)-10<<METADATA_FRACT_BITS)
}; };
static const FIXP_DBL tabMaxCutThr[] = { static const FIXP_DBL tabMaxCutThr[] = {
(FIXP_DBL)(4<<METADATA_FRACT_BITS), (FIXP_DBL)(4<<METADATA_FRACT_BITS),
@ -576,7 +576,7 @@ INT FDK_DRC_Generator_Initialize(
drcComp->channels = channelMapping.nChannels; drcComp->channels = channelMapping.nChannels;
/* Init states. */ /* Init states. */
drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(-135<<METADATA_FRACT_BITS); drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(int)((unsigned)-135<<METADATA_FRACT_BITS);
FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -107,6 +107,7 @@ typedef struct {
typedef struct { typedef struct {
ULONG brFrom; ULONG brFrom;
ULONG brTo; ULONG brTo;
UCHAR S16000;
UCHAR S22050; UCHAR S22050;
UCHAR S24000; UCHAR S24000;
UCHAR S32000; UCHAR S32000;
@ -115,25 +116,26 @@ typedef struct {
} AUTO_PNS_TAB; } AUTO_PNS_TAB;
static const AUTO_PNS_TAB levelTable_mono[]= { static const AUTO_PNS_TAB levelTable_mono[]= {
{0, 11999, 1, 1, 1, 1, 1,}, {0, 11999, 0, 1, 1, 1, 1, 1,},
{12000, 19999, 1, 1, 1, 1, 1,}, {12000, 19999, 0, 1, 1, 1, 1, 1,},
{20000, 28999, 2, 1, 1, 1, 1,}, {20000, 28999, 0, 2, 1, 1, 1, 1,},
{29000, 40999, 4, 4, 4, 2, 2,}, {29000, 40999, 0, 4, 4, 4, 2, 2,},
{41000, 55999, 9, 9, 7, 7, 7,}, {41000, 55999, 0, 9, 9, 7, 7, 7,},
{56000, 79999, 0, 0, 0, 9, 9,}, {56000, 61999, 0, 0, 0, 0, 9, 9,},
{80000, 99999, 0, 0, 0, 0, 0,}, {62000, 75999, 0, 0, 0, 0, 0, 0,},
{100000,999999, 0, 0, 0, 0, 0,}, {76000, 92999, 0, 0, 0, 0, 0, 0,},
{93000, 999999, 0, 0, 0, 0, 0, 0,},
}; };
static const AUTO_PNS_TAB levelTable_stereo[]= { static const AUTO_PNS_TAB levelTable_stereo[]= {
{0, 11999, 1, 1, 1, 1, 1,}, {0, 11999, 0, 1, 1, 1, 1, 1,},
{12000, 19999, 3, 1, 1, 1, 1,}, {12000, 19999, 0, 3, 1, 1, 1, 1,},
{20000, 28999, 3, 3, 3, 2, 2,}, {20000, 28999, 0, 3, 3, 3, 2, 2,},
{29000, 40999, 7, 6, 6, 5, 5,}, {29000, 40999, 0, 7, 6, 6, 5, 5,},
{41000, 55999, 9, 9, 7, 7, 7,}, {41000, 55999, 0, 9, 9, 7, 7, 7,},
{56000, 79999, 0, 0, 0, 0, 0,}, {56000, 79999, 0, 0, 0, 0, 0, 0,},
{80000, 99999, 0, 0, 0, 0, 0,}, {80000, 99999, 0, 0, 0, 0, 0, 0,},
{100000,999999, 0, 0, 0, 0, 0,}, {100000,999999, 0, 0, 0, 0, 0, 0,},
}; };
@ -160,11 +162,11 @@ static const PNS_INFO_TAB pnsInfoTab[] = {
}; };
static const AUTO_PNS_TAB levelTable_lowComplexity[]= { static const AUTO_PNS_TAB levelTable_lowComplexity[]= {
{0, 27999, 0, 0, 0, 0, 0,}, {0, 27999, 0, 0, 0, 0, 0, 0,},
{28000, 31999, 2, 2, 2, 2, 2,}, {28000, 31999, 0, 2, 2, 2, 2, 2,},
{32000, 47999, 3, 3, 3, 3, 3,}, {32000, 47999, 0, 3, 3, 3, 3, 3,},
{48000, 48000, 4, 4, 4, 4, 4,}, {48000, 48000, 0, 4, 4, 4, 4, 4,},
{48001, 999999, 0, 0, 0, 0, 0,}, {48001, 999999, 0, 0, 0, 0, 0, 0,},
}; };
/* conversion of old LC tuning tables to new (LD enc) structure (only entries which are actually used were converted) */ /* conversion of old LC tuning tables to new (LD enc) structure (only entries which are actually used were converted) */
@ -211,6 +213,7 @@ int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int
} }
switch (sampleRate) { switch (sampleRate) {
case 16000: hUsePns = levelTable[i].S16000; break;
case 22050: hUsePns = levelTable[i].S22050; break; case 22050: hUsePns = levelTable[i].S22050; break;
case 24000: hUsePns = levelTable[i].S24000; break; case 24000: hUsePns = levelTable[i].S24000; break;
case 32000: hUsePns = levelTable[i].S32000; break; case 32000: hUsePns = levelTable[i].S32000; break;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -634,13 +634,14 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate,
if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)
break; break;
} }
psyConf->sfbActive = sfb; psyConf->sfbActive = FDKmax(sfb, 1);
for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){ for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){
if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE)
break; break;
} }
psyConf->sfbActiveLFE = sfb; psyConf->sfbActiveLFE = sfb;
psyConf->sfbActive = FDKmax(psyConf->sfbActive, psyConf->sfbActiveLFE);
/* calculate minSnr */ /* calculate minSnr */
FDKaacEnc_initMinSnr(bitrate, FDKaacEnc_initMinSnr(bitrate,

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -342,6 +342,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
tnsChannels, tnsChannels,
LONG_WINDOW, LONG_WINDOW,
hPsy->granuleLength, hPsy->granuleLength,
isLowDelay(audioObjectType),
(syntaxFlags&AC_SBR_PRESENT)?1:0, (syntaxFlags&AC_SBR_PRESENT)?1:0,
&(hPsy->psyConf[0].tnsConf), &(hPsy->psyConf[0].tnsConf),
&hPsy->psyConf[0], &hPsy->psyConf[0],
@ -362,6 +363,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
tnsChannels, tnsChannels,
SHORT_WINDOW, SHORT_WINDOW,
hPsy->granuleLength, hPsy->granuleLength,
isLowDelay(audioObjectType),
(syntaxFlags&AC_SBR_PRESENT)?1:0, (syntaxFlags&AC_SBR_PRESENT)?1:0,
&hPsy->psyConf[1].tnsConf, &hPsy->psyConf[1].tnsConf,
&hPsy->psyConf[1], &hPsy->psyConf[1],
@ -447,7 +449,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
INT totalChannels INT totalChannels
) )
{ {
INT commonWindow = 1; const INT commonWindow = 1;
INT maxSfbPerGroup[(2)]; INT maxSfbPerGroup[(2)];
INT mdctSpectrum_e; INT mdctSpectrum_e;
INT ch; /* counts through channels */ INT ch; /* counts through channels */
@ -621,7 +623,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset], FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset],
(windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL)); (windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL));
if (hPsyConfLong->filterbank != FB_LC) { if ( (hPsyConfLong->filterbank != FB_LC) && (psyData[ch]->lowpassLine >= FADE_OUT_LEN) ) {
/* Do blending to reduce gibbs artifacts */ /* Do blending to reduce gibbs artifacts */
for (int i=0; i<FADE_OUT_LEN; i++) { for (int i=0; i<FADE_OUT_LEN; i++) {
psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]); psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]);
@ -763,7 +765,8 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
/* Advance psychoacoustics: Tonality and TNS */ /* Advance psychoacoustics: Tonality and TNS */
if (psyStatic[0]->isLFE) { if (psyStatic[0]->isLFE) {
tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive = 0; tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0;
tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0;
} }
else else
{ {
@ -815,15 +818,19 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
&hThisPsyConf[1]->tnsConf); &hThisPsyConf[1]->tnsConf);
} }
FDK_ASSERT(commonWindow=1); /* all checks for TNS do only work for common windows (which is always set)*/ FDK_ASSERT(1==commonWindow); /* all checks for TNS do only work for common windows (which is always set)*/
for(w = 0; w < nWindows[0]; w++) for(w = 0; w < nWindows[0]; w++)
{ {
if (isShortWindow[0]) if (isShortWindow[0])
tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive || tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
((channels == 2) ? tnsData[1]->dataRaw.Short.subBlockInfo[w].tnsActive : 0); tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] ||
tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT];
else else
tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive || tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
((channels == 2) ? tnsData[1]->dataRaw.Long.subBlockInfo.tnsActive : 0); tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] ||
tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT];
} }
for(ch = 0; ch < channels; ch++) { for(ch = 0; ch < channels; ch++) {
@ -1150,8 +1157,8 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
psyData[ch]->sfbMaxScaleSpec.Long, psyData[ch]->sfbMaxScaleSpec.Long,
sfbTonality[ch], sfbTonality[ch],
psyOutChannel[ch]->tnsInfo.order[0][0], psyOutChannel[ch]->tnsInfo.order[0][0],
tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain, tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT],
tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive, tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT],
psyOutChannel[ch]->sfbEnergyLdData, psyOutChannel[ch]->sfbEnergyLdData,
psyOutChannel[ch]->noiseNrg ); psyOutChannel[ch]->noiseNrg );
} /* !isLFE */ } /* !isLFE */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -269,6 +269,8 @@ typedef struct
BITCNTR_STATE *hBitCounter; BITCNTR_STATE *hBitCounter;
ADJ_THR_STATE *hAdjThr; ADJ_THR_STATE *hAdjThr;
INT dZoneQuantEnable; /* enable dead zone quantizer */
} QC_STATE; } QC_STATE;
#endif /* _QC_DATA_H */ #endif /* _QC_DATA_H */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -107,14 +107,11 @@ typedef struct {
} TAB_VBR_QUAL_FACTOR; } TAB_VBR_QUAL_FACTOR;
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = { static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
{QCDATA_BR_MODE_CBR, FL2FXCONST_DBL(0.00f)},
{QCDATA_BR_MODE_VBR_1, FL2FXCONST_DBL(0.160f)}, /* 32 kbps mono AAC-LC + SBR + PS */ {QCDATA_BR_MODE_VBR_1, FL2FXCONST_DBL(0.160f)}, /* 32 kbps mono AAC-LC + SBR + PS */
{QCDATA_BR_MODE_VBR_2, FL2FXCONST_DBL(0.148f)}, /* 64 kbps stereo AAC-LC + SBR */ {QCDATA_BR_MODE_VBR_2, FL2FXCONST_DBL(0.148f)}, /* 64 kbps stereo AAC-LC + SBR */
{QCDATA_BR_MODE_VBR_3, FL2FXCONST_DBL(0.135f)}, /* 80 - 96 kbps stereo AAC-LC */ {QCDATA_BR_MODE_VBR_3, FL2FXCONST_DBL(0.135f)}, /* 80 - 96 kbps stereo AAC-LC */
{QCDATA_BR_MODE_VBR_4, FL2FXCONST_DBL(0.111f)}, /* 128 kbps stereo AAC-LC */ {QCDATA_BR_MODE_VBR_4, FL2FXCONST_DBL(0.111f)}, /* 128 kbps stereo AAC-LC */
{QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)}, /* 192 kbps stereo AAC-LC */ {QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)} /* 192 kbps stereo AAC-LC */
{QCDATA_BR_MODE_SFR, FL2FXCONST_DBL(0.00f)},
{QCDATA_BR_MODE_FF, FL2FXCONST_DBL(0.00f)}
}; };
static INT isConstantBitrateMode( static INT isConstantBitrateMode(
@ -369,6 +366,7 @@ QCNew_bail:
AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
struct QC_INIT *init) struct QC_INIT *init)
{ {
int i;
hQC->maxBitsPerFrame = init->maxBits; hQC->maxBitsPerFrame = init->maxBits;
hQC->minBitsPerFrame = init->minBits; hQC->minBitsPerFrame = init->minBits;
hQC->nElements = init->channelMapping->nElements; hQC->nElements = init->channelMapping->nElements;
@ -382,7 +380,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
if ( isConstantBitrateMode(hQC->bitrateMode) ) { if ( isConstantBitrateMode(hQC->bitrateMode) ) {
INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff); INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff);
/* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */ /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
hQC->bitDistributionMode = (bitresPerChannel>100) ? 0 : (bitresPerChannel>0) ? 1 : 2; hQC->bitDistributionMode = (bitresPerChannel>BITRES_MIN_LD) ? 0 : (bitresPerChannel>0) ? 1 : 2;
} }
else { else {
hQC->bitDistributionMode = 0; /* full bitreservoir */ hQC->bitDistributionMode = 0; /* full bitreservoir */
@ -399,25 +397,22 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
(init->averageBits/init->nSubFrames) - hQC->globHdrBits, (init->averageBits/init->nSubFrames) - hQC->globHdrBits,
hQC->maxBitsPerFrame/init->channelMapping->nChannelsEff); hQC->maxBitsPerFrame/init->channelMapping->nChannelsEff);
switch(hQC->bitrateMode){ hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
case QCDATA_BR_MODE_CBR: for (i=0; i<(int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR)); i++) {
case QCDATA_BR_MODE_VBR_1: if (hQC->bitrateMode==tableVbrQualFactor[i].bitrateMode) {
case QCDATA_BR_MODE_VBR_2: hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor;
case QCDATA_BR_MODE_VBR_3:
case QCDATA_BR_MODE_VBR_4:
case QCDATA_BR_MODE_VBR_5:
case QCDATA_BR_MODE_SFR:
case QCDATA_BR_MODE_FF:
if((int)hQC->bitrateMode < (int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR))){
hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[hQC->bitrateMode].vbrQualFactor;
} else {
hQC->vbrQualFactor = FL2FXCONST_DBL(0.f); /* default setting */
}
break;
case QCDATA_BR_MODE_INVALID:
default:
hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
break; break;
}
}
if (init->channelMapping->nChannelsEff == 1 &&
(init->bitrate / init->channelMapping->nChannelsEff) < 32000 &&
init->advancedBitsToPe != 0
)
{
hQC->dZoneQuantEnable = 1;
} else {
hQC->dZoneQuantEnable = 0;
} }
FDKaacEnc_AdjThrInit( FDKaacEnc_AdjThrInit(
@ -429,7 +424,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
init->channelMapping->nChannelsEff, init->channelMapping->nChannelsEff,
init->sampleRate, /* output sample rate */ init->sampleRate, /* output sample rate */
init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */ init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */
hQC->vbrQualFactor hQC->vbrQualFactor,
hQC->dZoneQuantEnable
); );
return AAC_ENC_OK; return AAC_ENC_OK;
@ -892,6 +888,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
qcOut[c], qcOut[c],
psyOut[c]->psyOutElement, psyOut[c]->psyOutElement,
isConstantBitrateMode(hQC->bitrateMode), isConstantBitrateMode(hQC->bitrateMode),
hQC->hAdjThr->maxIter2ndGuess,
cm); cm);
} /* -end- sub frame counter */ } /* -end- sub frame counter */
@ -919,6 +916,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel, FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel,
qcElement[c][i]->qcOutChannel, qcElement[c][i]->qcOutChannel,
hQC->invQuant, hQC->invQuant,
hQC->dZoneQuantEnable,
cm->elInfo[i].nChannelsInEl); cm->elInfo[i].nChannelsInEl);
@ -1013,7 +1011,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
qcOutCh->mdctSpectrum, qcOutCh->mdctSpectrum,
qcOutCh->globalGain, qcOutCh->globalGain,
qcOutCh->scf, qcOutCh->scf,
qcOutCh->quantSpec) ; qcOutCh->quantSpec,
hQC->dZoneQuantEnable);
/*-------------------------------------------- */ /*-------------------------------------------- */
if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt, if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt,
@ -1263,6 +1262,8 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
case QCDATA_BR_MODE_VBR_4: case QCDATA_BR_MODE_VBR_4:
case QCDATA_BR_MODE_VBR_5: case QCDATA_BR_MODE_VBR_5:
qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */ qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */
qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits;
qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
break; break;
case QCDATA_BR_MODE_CBR: case QCDATA_BR_MODE_CBR:
@ -1272,6 +1273,8 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
/* processing fill-bits */ /* processing fill-bits */
INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ; INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ;
qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7))); qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7)));
qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits;
qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
break; break;
} /* switch (qcKernel->bitrateMode) */ } /* switch (qcKernel->bitrateMode) */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -104,13 +104,19 @@ amm-info@iis.fraunhofer.de
static void FDKaacEnc_quantizeLines(INT gain, static void FDKaacEnc_quantizeLines(INT gain,
INT noOfLines, INT noOfLines,
FIXP_DBL *mdctSpectrum, FIXP_DBL *mdctSpectrum,
SHORT *quaSpectrum) SHORT *quaSpectrum,
INT dZoneQuantEnable)
{ {
int line; int line;
FIXP_DBL k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>16; FIXP_DBL k = FL2FXCONST_DBL(0.0f);
FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3]; FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3];
INT quantizershift = ((-gain)>>2)+1; INT quantizershift = ((-gain)>>2)+1;
const INT kShift=16;
if (dZoneQuantEnable)
k = FL2FXCONST_DBL(0.23f)>>kShift;
else
k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>kShift;
for (line = 0; line < noOfLines; line++) for (line = 0; line < noOfLines; line++)
{ {
@ -263,7 +269,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
FIXP_DBL *mdctSpectrum, FIXP_DBL *mdctSpectrum,
INT globalGain, INT globalGain,
INT *scalefactors, INT *scalefactors,
SHORT *quantizedSpectrum) SHORT *quantizedSpectrum,
INT dZoneQuantEnable)
{ {
INT sfbOffs,sfb; INT sfbOffs,sfb;
@ -280,7 +287,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */ FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */
sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb], sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb],
mdctSpectrum + sfbOffset[sfbOffs+sfb], mdctSpectrum + sfbOffset[sfbOffs+sfb],
quantizedSpectrum + sfbOffset[sfbOffs+sfb]); quantizedSpectrum + sfbOffset[sfbOffs+sfb],
dZoneQuantEnable);
} }
} }
@ -296,7 +304,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
SHORT *quantSpectrum, SHORT *quantSpectrum,
INT noOfLines, INT noOfLines,
INT gain INT gain,
INT dZoneQuantEnable
) )
{ {
INT i,scale; INT i,scale;
@ -311,7 +320,8 @@ FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
FDKaacEnc_quantizeLines(gain, FDKaacEnc_quantizeLines(gain,
1, 1,
&mdctSpectrum[i], &mdctSpectrum[i],
&quantSpectrum[i]); &quantSpectrum[i],
dZoneQuantEnable);
if (fAbs(quantSpectrum[i])>MAX_QUANT) { if (fAbs(quantSpectrum[i])>MAX_QUANT) {
return FL2FXCONST_DBL(0.0f); return FL2FXCONST_DBL(0.0f);

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -102,12 +102,14 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
INT sfbPerGroup, INT sfbPerGroup,
INT *sfbOffset, FIXP_DBL *mdctSpectrum, INT *sfbOffset, FIXP_DBL *mdctSpectrum,
INT globalGain, INT *scalefactors, INT globalGain, INT *scalefactors,
SHORT *quantizedSpectrum); SHORT *quantizedSpectrum,
INT dZoneQuantEnable);
FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
SHORT *quantSpectrum, SHORT *quantSpectrum,
INT noOfLines, INT noOfLines,
INT gain); INT gain,
INT dZoneQuantEnable);
void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum, void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
SHORT *quantSpectrum, SHORT *quantSpectrum,

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -363,7 +363,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
INT scf, INT scf,
INT minScf, INT minScf,
FIXP_DBL *distLdData, FIXP_DBL *distLdData,
INT *minScfCalculated INT *minScfCalculated,
INT dZoneQuantEnable
) )
{ {
FIXP_DBL sfbDistLdData; FIXP_DBL sfbDistLdData;
@ -375,7 +376,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec, sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpec, quantSpec,
sfbWidth, sfbWidth,
scf); scf,
dZoneQuantEnable);
*minScfCalculated = scf; *minScfCalculated = scf;
/* nmr > 1.25 -> try to improve nmr */ /* nmr > 1.25 -> try to improve nmr */
if (sfbDistLdData > (threshLdData-distFactorLdData)) { if (sfbDistLdData > (threshLdData-distFactorLdData)) {
@ -390,7 +392,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec, sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpecTmp, quantSpecTmp,
sfbWidth, sfbWidth,
scf); scf,
dZoneQuantEnable);
if (sfbDistLdData < sfbDistBestLdData) { if (sfbDistLdData < sfbDistBestLdData) {
scfBest = scf; scfBest = scf;
@ -408,7 +411,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec, sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpecTmp, quantSpecTmp,
sfbWidth, sfbWidth,
scf); scf,
dZoneQuantEnable);
if (sfbDistLdData < sfbDistBestLdData) { if (sfbDistLdData < sfbDistBestLdData) {
scfBest = scf; scfBest = scf;
@ -429,7 +433,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec, sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpecTmp, quantSpecTmp,
sfbWidth, sfbWidth,
scf); scf,
dZoneQuantEnable);
if (sfbDistLdData < sfbDistAllowedLdData) { if (sfbDistLdData < sfbDistAllowedLdData) {
*minScfCalculated = scfBest+1; *minScfCalculated = scfBest+1;
@ -454,6 +459,7 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
QC_OUT_CHANNEL *qcOutChannel, QC_OUT_CHANNEL *qcOutChannel,
SHORT *quantSpec, SHORT *quantSpec,
SHORT *quantSpecTmp, SHORT *quantSpecTmp,
INT dZoneQuantEnable,
INT *scf, INT *scf,
INT *minScf, INT *minScf,
FIXP_DBL *sfbDist, FIXP_DBL *sfbDist,
@ -570,7 +576,8 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs, sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
quantSpecTmp+sfbOffs, quantSpecTmp+sfbOffs,
sfbWidth, sfbWidth,
scfAct); scfAct,
dZoneQuantEnable);
if (sfbDistNew < sfbDist[sfbAct]) { if (sfbDistNew < sfbDist[sfbAct]) {
/* success, replace scf by new one */ /* success, replace scf by new one */
@ -629,6 +636,7 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
QC_OUT_CHANNEL *qcOutChannel, QC_OUT_CHANNEL *qcOutChannel,
SHORT *quantSpec, SHORT *quantSpec,
SHORT *quantSpecTmp, SHORT *quantSpecTmp,
INT dZoneQuantEnable,
INT *scf, INT *scf,
INT *minScf, INT *minScf,
FIXP_DBL *sfbDist, FIXP_DBL *sfbDist,
@ -724,7 +732,8 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs, sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
quantSpecTmp+sfbOffs, quantSpecTmp+sfbOffs,
sfbWidth, sfbWidth,
scfAct); scfAct,
dZoneQuantEnable);
if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) { if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) {
/* no improvement, skip further dist. calculations */ /* no improvement, skip further dist. calculations */
@ -768,6 +777,7 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
QC_OUT_CHANNEL *qcOutChannel, QC_OUT_CHANNEL *qcOutChannel,
SHORT *quantSpec, SHORT *quantSpec,
SHORT *quantSpecTmp, SHORT *quantSpecTmp,
INT dZoneQuantEnable,
INT *scf, INT *scf,
INT *minScf, INT *minScf,
FIXP_DBL *sfbDist, FIXP_DBL *sfbDist,
@ -883,7 +893,8 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb], sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
quantSpecTmp+sfbOffs[sfb], quantSpecTmp+sfbOffs[sfb],
sfbOffs[sfb+1]-sfbOffs[sfb], sfbOffs[sfb+1]-sfbOffs[sfb],
scfNew); scfNew,
dZoneQuantEnable);
if (sfbDistNew[sfb] > sfbDistMax[sfb]) { if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
/* no improvement, skip further dist. calculations */ /* no improvement, skip further dist. calculations */
@ -963,7 +974,8 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb], sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
quantSpecTmp+sfbOffs[sfb], quantSpecTmp+sfbOffs[sfb],
sfbOffs[sfb+1]-sfbOffs[sfb], sfbOffs[sfb+1]-sfbOffs[sfb],
scfNew); scfNew,
dZoneQuantEnable);
if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
/* no improvement, skip further dist. calculations */ /* no improvement, skip further dist. calculations */
@ -1058,7 +1070,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
INT *RESTRICT globalGain, INT *RESTRICT globalGain,
FIXP_DBL *RESTRICT sfbFormFactorLdData FIXP_DBL *RESTRICT sfbFormFactorLdData
,const INT invQuant, ,const INT invQuant,
SHORT *RESTRICT quantSpec SHORT *RESTRICT quantSpec,
const INT dZoneQuantEnable
) )
{ {
INT i, j, sfb, sfbOffs; INT i, j, sfb, sfbOffs;
@ -1160,7 +1173,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb], quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb],
psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb], psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb], threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb],
&sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb] &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb],
dZoneQuantEnable
); );
} }
scf[sfbOffs+sfb] = scfInt; scf[sfbOffs+sfb] = scfInt;
@ -1187,20 +1201,32 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
sfbNRelevantLines); sfbNRelevantLines);
FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf, FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
dZoneQuantEnable,
scf,
minSfMaxQuant, sfbDistLdData, sfbConstPePart, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1); sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1);
if(invQuant > 1) {
FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
dZoneQuantEnable,
scf,
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
sfbFormFactorLdData, sfbNRelevantLines);
FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf, FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
minSfMaxQuant, sfbDistLdData, sfbConstPePart, dZoneQuantEnable,
sfbFormFactorLdData, sfbNRelevantLines); scf,
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
sfbFormFactorLdData, sfbNRelevantLines);
FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf, FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
minSfMaxQuant, sfbDistLdData, sfbConstPePart, dZoneQuantEnable,
sfbFormFactorLdData, sfbNRelevantLines); scf,
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
sfbFormFactorLdData, sfbNRelevantLines);
}
} }
@ -1223,7 +1249,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb], FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb], quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb], psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
scf[sfbOffs+sfb] scf[sfbOffs+sfb],
dZoneQuantEnable
); );
} }
} }
@ -1281,6 +1308,7 @@ void
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
QC_OUT_CHANNEL* qcOutChannel[], QC_OUT_CHANNEL* qcOutChannel[],
const int invQuant, const int invQuant,
const INT dZoneQuantEnable,
const int nChannels) const int nChannels)
{ {
int ch; int ch;
@ -1293,7 +1321,8 @@ FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
&qcOutChannel[ch]->globalGain, &qcOutChannel[ch]->globalGain,
qcOutChannel[ch]->sfbFormFactorLdData qcOutChannel[ch]->sfbFormFactorLdData
,invQuant, ,invQuant,
qcOutChannel[ch]->quantSpec qcOutChannel[ch]->quantSpec,
dZoneQuantEnable
); );
} }

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -110,6 +110,7 @@ void
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
QC_OUT_CHANNEL* qcOutChannel[], QC_OUT_CHANNEL* qcOutChannel[],
const int invQuant, const int invQuant,
const INT dZoneQuantEnable,
const int nChannels); const int nChannels);

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -100,6 +100,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitrate,
INT channels, INT channels,
INT blocktype, INT blocktype,
INT granuleLength, INT granuleLength,
INT isLowDelay,
INT ldSbrPresent, INT ldSbrPresent,
TNS_CONFIG *tnsConfig, TNS_CONFIG *tnsConfig,
PSY_CONFIGURATION *psyConfig, PSY_CONFIGURATION *psyConfig,

View File

@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de
/* Take action against VisualStudio 2005 crosscompile problems. */ /* Take action against VisualStudio 2005 crosscompile problems. */
/* Use single macro (the GCC built in macro) for architecture identification independent of the particular toolchain */ /* 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__ #define __x86__
#endif #endif
@ -154,7 +154,6 @@ amm-info@iis.fraunhofer.de
#endif #endif
#ifdef _M_ARM #ifdef _M_ARM
#include "cmnintrin.h"
#include "armintr.h" #include "armintr.h"
#endif #endif
@ -198,6 +197,14 @@ amm-info@iis.fraunhofer.de
#undef POW2COEFF_16BIT #undef POW2COEFF_16BIT
#undef LDCOEFF_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 */ #elif defined(__x86__) /* cppp replaced: elif */
#define ARCH_PREFER_MULT_32x16 #define ARCH_PREFER_MULT_32x16
#define SINETABLE_16BIT #define SINETABLE_16BIT

View File

@ -81,13 +81,42 @@ www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */ ----------------------------------------------------------------------------------------------------------- */
/*************************** MPEG AAC Audio Encoder ************************* /*************************** Fraunhofer IIS FDK Tools **********************
Initial author: R. Boehm Author(s):
contents/description: huffman codeword reordering Description: fixed point intrinsics
based on source from aacErrRobTrans
******************************************************************************/ ******************************************************************************/
#include "aacenc_hcr.h" #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

@ -81,16 +81,33 @@ www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */ ----------------------------------------------------------------------------------------------------------- */
/*************************** MPEG AAC Audio Encoder ************************* /*************************** Fraunhofer IIS FDK Tools **********************
Initial author: R. Boehm Author(s):
contents/description: huffman codeword reordering Description: fixed point intrinsics
based on source from aacErrRobTrans
******************************************************************************/ ******************************************************************************/
#ifndef _AACENC_HCR #if defined(__aarch64__) || defined(__AARCH64EL__)
#define _AACENC_HCR_H
#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__ */
#endif /* ifndef _AACENC_HCR */

View File

@ -97,6 +97,9 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__) #if defined(__arm__)
#include "arm/clz_arm.h" #include "arm/clz_arm.h"
#elif defined(__aarch64__) || defined(__AARCH64EL__)
#include "aarch64/clz_aarch64.h"
#elif defined(__mips__) /* cppp replaced: elif */ #elif defined(__mips__) /* cppp replaced: elif */
#include "mips/clz_mips.h" #include "mips/clz_mips.h"

View File

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

View File

@ -98,6 +98,9 @@ amm-info@iis.fraunhofer.de
#if defined(__arm__) #if defined(__arm__)
#include "arm/fixmul_arm.h" #include "arm/fixmul_arm.h"
#elif defined(__aarch64__) || defined(__AARCH64EL__)
#include "aarch64/fixmul_aarch64.h"
#elif defined(__mips__) /* cppp replaced: elif */ #elif defined(__mips__) /* cppp replaced: elif */
#include "mips/fixmul_mips.h" #include "mips/fixmul_mips.h"

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2014 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -94,6 +94,35 @@ amm-info@iis.fraunhofer.de
#include "common_fix.h" #include "common_fix.h"
#if !defined(FUNCTION_fIsLessThan)
/**
* \brief Compares two fixpoint values incl. scaling.
* \param a_m mantissa of the first input value.
* \param a_e exponent of the first input value.
* \param b_m mantissa of the second input value.
* \param b_e exponent of the second input value.
* \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
*/
FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e)
{
if (a_e > b_e) {
return (b_m >> fMin(a_e-b_e, DFRACT_BITS-1) > a_m);
} else {
return (a_m >> fMin(b_e-a_e, DFRACT_BITS-1) < b_m);
}
}
FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e)
{
if (a_e > b_e) {
return (b_m >> fMin(a_e-b_e, FRACT_BITS-1) > a_m);
} else {
return (a_m >> fMin(b_e-a_e, FRACT_BITS-1) < b_m);
}
}
#endif
#define LD_DATA_SCALING (64.0f) #define LD_DATA_SCALING (64.0f)
#define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */ #define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */

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 //#define FUNCTION_cplxMultDiv2_32x16
@ -107,24 +107,8 @@ inline void cplxMultDiv2( FIXP_DBL *c_Re,
FIXP_DBL b_Re, FIXP_DBL b_Re,
FIXP_DBL b_Im) FIXP_DBL b_Im)
{ {
INT 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;
__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;
} }
#endif #endif
@ -136,25 +120,8 @@ inline void cplxMult( FIXP_DBL *c_Re,
FIXP_DBL b_Re, FIXP_DBL b_Re,
FIXP_DBL b_Im) FIXP_DBL b_Im)
{ {
INT result; *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;
__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;
} }
#endif #endif

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -93,10 +93,15 @@ amm-info@iis.fraunhofer.de
/* FDK tools library info */ /* FDK tools library info */
#define FDK_TOOLS_LIB_VL0 2 #define FDK_TOOLS_LIB_VL0 2
#define FDK_TOOLS_LIB_VL1 3 #define FDK_TOOLS_LIB_VL1 3
#define FDK_TOOLS_LIB_VL2 2 #define FDK_TOOLS_LIB_VL2 6
#define FDK_TOOLS_LIB_TITLE "FDK Tools" #define FDK_TOOLS_LIB_TITLE "FDK Tools"
#ifdef __ANDROID__
#define FDK_TOOLS_LIB_BUILD_DATE ""
#define FDK_TOOLS_LIB_BUILD_TIME ""
#else
#define FDK_TOOLS_LIB_BUILD_DATE __DATE__ #define FDK_TOOLS_LIB_BUILD_DATE __DATE__
#define FDK_TOOLS_LIB_BUILD_TIME __TIME__ #define FDK_TOOLS_LIB_BUILD_TIME __TIME__
#endif
int FDK_toolsGetLibInfo(LIB_INFO *info) int FDK_toolsGetLibInfo(LIB_INFO *info)
{ {

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1260,9 +1260,9 @@ const FIXP_WTP * FDKgetWindowSlope(int length, int shape)
#define QTCFL(x) FL2FXCONST_SGL(x) #define QTCFL(x) FL2FXCONST_SGL(x)
#define QTC(x) FX_DBL2FXCONST_SGL(x) #define QTC(x) FX_DBL2FXCONST_SGL(x)
#else #else
#define QFC(x) (x) #define QFC(x) ((FIXP_DBL)(x))
#define QTCFL(x) FL2FXCONST_DBL(x) #define QTCFL(x) FL2FXCONST_DBL(x)
#define QTC(x) (x) #define QTC(x) ((FIXP_DBL)(x))
#endif /* ARCH_PREFER_MULT_32x16 */ #endif /* ARCH_PREFER_MULT_32x16 */
#ifndef LOW_POWER_SBR_ONLY #ifndef LOW_POWER_SBR_ONLY
@ -2039,19 +2039,6 @@ static const element_list_t node_aac_cpe = {
{ &node_aac_cpe0, &node_aac_cpe1 } { &node_aac_cpe0, &node_aac_cpe1 }
}; };
#define el_mpegsres_sce &el_aac_sce[2]
static const element_list_t node_mpegsres_sce = {
el_mpegsres_sce,
{ NULL, NULL }
};
static const element_list_t node_mpegsres_cpe = {
el_aac_cpe1,
{ NULL, NULL }
};
/* /*
* AOT C- {17,23} * AOT C- {17,23}
* epConfig = 0,1 * epConfig = 0,1
@ -2249,7 +2236,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = {
ics_info, ics_info,
ms, ms,
ltp_data_present, ltp_data_present,
ltp_data, /* ltp_data, */
global_gain, global_gain,
section_data, section_data,
scale_factor_data, scale_factor_data,
@ -2260,7 +2247,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = {
next_channel, next_channel,
ltp_data_present, ltp_data_present,
ltp_data, /* ltp_data, */
global_gain, global_gain,
section_data, section_data,
scale_factor_data, scale_factor_data,
@ -2303,7 +2290,178 @@ static const element_list_t node_aac_cpe_epc1 = {
{ &node_aac_cpe0_epc1, &node_aac_cpe1_epc1 } { &node_aac_cpe0_epc1, &node_aac_cpe1_epc1 }
}; };
/*
* AOT = 20
* epConfig = 0
*/
static const rbd_id_t el_scal_sce_epc0[] = {
ics_info, /* ESC 1 */
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
esc2_rvlc, /* ESC 2 */
tns_data, /* ESC 3 */
spectral_data, /* ESC 4 */
end_of_sequence
};
static const struct element_list node_scal_sce_epc0 = {
el_scal_sce_epc0,
{ NULL, NULL }
};
static const rbd_id_t el_scal_cpe_epc0[] = {
ics_info, /* ESC 0 */
ms,
tns_data_present, /* ESC 1 (ch 0) */
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
esc2_rvlc, /* ESC 2 (ch 0) */
tns_data, /* ESC 3 (ch 0) */
spectral_data, /* ESC 4 (ch 0) */
next_channel,
tns_data_present, /* ESC 1 (ch 1) */
ltp_data_present,
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
esc2_rvlc, /* ESC 2 (ch 1) */
tns_data, /* ESC 3 (ch 1) */
spectral_data, /* ESC 4 (ch 1) */
end_of_sequence
};
static const struct element_list node_scal_cpe_epc0 = {
el_scal_cpe_epc0,
{ NULL, NULL }
};
/*
* AOT = 20
* epConfig = 1
*/
static const rbd_id_t el_scal_sce_epc1[] = {
ics_info,
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
tns_data,
spectral_data,
end_of_sequence
};
static const struct element_list node_scal_sce_epc1 = {
el_scal_sce_epc1,
{ NULL, NULL }
};
static const rbd_id_t el_scal_cpe_epc1[] = {
ics_info,
ms,
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
next_channel,
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
next_channel,
tns_data,
next_channel,
tns_data,
next_channel,
spectral_data,
next_channel,
spectral_data,
end_of_sequence
};
static const struct element_list node_scal_cpe_epc1 = {
el_scal_cpe_epc1,
{ NULL, NULL }
};
/*
* Pseudo AOT for DRM/DRM+ (similar to AOT 20)
* Derived from epConfig = 1
*/
static const rbd_id_t el_drm_sce[] = {
drmcrc_start_reg,
ics_info,
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
tns_data,
drmcrc_end_reg,
spectral_data,
end_of_sequence
};
static const struct element_list node_drm_sce = {
el_drm_sce,
{ NULL, NULL }
};
static const rbd_id_t el_drm_cpe[] = {
drmcrc_start_reg,
ics_info,
ms,
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
next_channel,
tns_data_present,
ltp_data_present,
/* ltp_data, */
global_gain,
section_data,
scale_factor_data,
esc1_hcr,
next_channel,
tns_data,
next_channel,
tns_data,
drmcrc_end_reg,
next_channel,
spectral_data,
next_channel,
spectral_data,
end_of_sequence
};
static const struct element_list node_drm_cpe = {
el_drm_cpe,
{ NULL, NULL }
};
/* /*
* AOT = 39 * AOT = 39
@ -2418,6 +2576,19 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo
return &node_aac_cpe_epc1; return &node_aac_cpe_epc1;
} }
break; break;
case AOT_ER_AAC_SCAL:
if (nChannels == 1) {
if (epConfig <= 0)
return &node_scal_sce_epc0;
else
return &node_scal_sce_epc1;
} else {
if (epConfig <= 0)
return &node_scal_cpe_epc0;
else
return &node_scal_cpe_epc1;
}
break;
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
if (nChannels == 1) { if (nChannels == 1) {
if (epConfig <= 0) if (epConfig <= 0)
@ -2430,11 +2601,14 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo
else else
return &node_eld_cpe_epc1; return &node_eld_cpe_epc1;
} }
case AOT_MPEGS_RESIDUALS: case AOT_DRM_AAC:
case AOT_DRM_SBR:
case AOT_DRM_MPEG_PS:
FDK_ASSERT(epConfig == 1);
if (nChannels == 1) { if (nChannels == 1) {
return &node_mpegsres_sce; return &node_drm_sce;
} else { } else {
return &node_mpegsres_cpe; return &node_drm_cpe;
} }
break; break;
default: default:

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -482,42 +482,42 @@ static void qmfSynPrototypeFirSlot1_filter(FIXP_QMF *RESTRICT realSlot,
B = p_flt[4]; /* Bottom=[8] Top=[9] */ B = p_flt[4]; /* Bottom=[8] Top=[9] */
A = p_fltm[3]; /* Bottom=[316] Top=[317] */ A = p_fltm[3]; /* Bottom=[316] Top=[317] */
sta0 = sta[0]; /* save state[0] */ sta0 = sta[0]; /* save state[0] */
*sta++ = SMLAWT( sta[1], imag, B ); /* index=9...........319 */ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=9...........319 */
*sta++ = SMLAWB( sta[1], real, A ); /* index=316...........6 */ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=316...........6 */
*sta++ = SMLAWB( sta[1], imag, B ); /* index=8,18, ...318 */ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=8,18, ...318 */
B = p_flt[3]; /* Bottom=[6] Top=[7] */ B = p_flt[3]; /* Bottom=[6] Top=[7] */
*sta++ = SMLAWT( sta[1], real, A ); /* index=317...........7 */ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=317...........7 */
A = p_fltm[4]; /* Bottom=[318] Top=[319] */ A = p_fltm[4]; /* Bottom=[318] Top=[319] */
*sta++ = SMLAWT( sta[1], imag, B ); /* index=7...........317 */ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=7...........317 */
*sta++ = SMLAWB( sta[1], real, A ); /* index=318...........8 */ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=318...........8 */
*sta++ = SMLAWB( sta[1], imag, B ); /* index=6...........316 */ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=6...........316 */
B = p_flt[2]; /* Bottom=[X] Top=[5] */ B = p_flt[2]; /* Bottom=[X] Top=[5] */
*sta++ = SMLAWT( sta[1], real, A ); /* index=9...........319 */ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=9...........319 */
A = p_fltm[2]; /* Bottom=[X] Top=[315] */ A = p_fltm[2]; /* Bottom=[X] Top=[315] */
*sta++ = SMULWT( imag, B ); /* index=5,15, ... 315 */ sta[0] = SMULWT( imag, B ); sta++; /* index=5,15, ... 315 */
result = SMLAWT( sta0, real, A ); /* index=315...........5 */ result = SMLAWT( sta0, real, A ); /* index=315...........5 */
*pMyTimeOut++ = result; pMyTimeOut[0] = result; pMyTimeOut++;
real = *--realSlot; real = *--realSlot;
imag = *--imagSlot; imag = *--imagSlot;
A = p_fltm[0]; /* Bottom=[310] Top=[311] */ A = p_fltm[0]; /* Bottom=[310] Top=[311] */
B = p_flt[7]; /* Bottom=[14] Top=[15] */ B = p_flt[7]; /* Bottom=[14] Top=[15] */
result = SMLAWB( sta[0], real, A ); /* index=310...........0 */ result = SMLAWB( sta[0], real, A ); /* index=310...........0 */
*sta++ = SMLAWB( sta[1], imag, B ); /* index=14..........324 */ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=14..........324 */
*pMyTimeOut++ = result; pMyTimeOut[0] = result; pMyTimeOut++;
B = p_flt[6]; /* Bottom=[12] Top=[13] */ B = p_flt[6]; /* Bottom=[12] Top=[13] */
*sta++ = SMLAWT( sta[1], real, A ); /* index=311...........1 */ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=311...........1 */
A = p_fltm[1]; /* Bottom=[312] Top=[313] */ A = p_fltm[1]; /* Bottom=[312] Top=[313] */
*sta++ = SMLAWT( sta[1], imag, B ); /* index=13..........323 */ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=13..........323 */
*sta++ = SMLAWB( sta[1], real, A ); /* index=312...........2 */ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=312...........2 */
*sta++ = SMLAWB( sta[1], imag, B ); /* index=12..........322 */ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=12..........322 */
*sta++ = SMLAWT( sta[1], real, A ); /* index=313...........3 */ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=313...........3 */
A = p_fltm[2]; /* Bottom=[314] Top=[315] */ A = p_fltm[2]; /* Bottom=[314] Top=[315] */
B = p_flt[5]; /* Bottom=[10] Top=[11] */ B = p_flt[5]; /* Bottom=[10] Top=[11] */
*sta++ = SMLAWT( sta[1], imag, B ); /* index=11..........321 */ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=11..........321 */
*sta++ = SMLAWB( sta[1], real, A ); /* index=314...........4 */ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=314...........4 */
*sta++ = SMULWB( imag, B ); /* index=10..........320 */ sta[0] = SMULWB( imag, B ); sta++; /* index=10..........320 */
p_flt += 5; p_flt += 5;
@ -566,21 +566,21 @@ INT qmfSynPrototypeFirSlot2(
A = p_fltm[0]; /* Bottom=[310] Top=[311] */ A = p_fltm[0]; /* Bottom=[310] Top=[311] */
B = p_flt[7]; /* Bottom=[14] Top=[15] */ B = p_flt[7]; /* Bottom=[14] Top=[15] */
result = SMLAWB( sta[0], real, A ); /* index=310...........0 */ result = SMLAWB( sta[0], real, A ); /* index=310...........0 */
*sta++ = SMLAWB( sta[1], imag, B ); /* index=14..........324 */ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=14..........324 */
B = p_flt[6]; /* Bottom=[12] Top=[13] */ B = p_flt[6]; /* Bottom=[12] Top=[13] */
*sta++ = SMLAWT( sta[1], real, A ); /* index=311...........1 */ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=311...........1 */
A = p_fltm[1]; /* Bottom=[312] Top=[313] */ A = p_fltm[1]; /* Bottom=[312] Top=[313] */
*sta++ = SMLAWT( sta[1], imag, B ); /* index=13..........323 */ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=13..........323 */
*sta++ = SMLAWB( sta[1], real, A ); /* index=312...........2 */ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=312...........2 */
*sta++ = SMLAWB( sta[1], imag, B ); /* index=12..........322 */ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=12..........322 */
*sta++ = SMLAWT( sta[1], real, A ); /* index=313...........3 */ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=313...........3 */
A = p_fltm[2]; /* Bottom=[314] Top=[315] */ A = p_fltm[2]; /* Bottom=[314] Top=[315] */
B = p_flt[5]; /* Bottom=[10] Top=[11] */ B = p_flt[5]; /* Bottom=[10] Top=[11] */
*sta++ = SMLAWT( sta[1], imag, B ); /* index=11..........321 */ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=11..........321 */
*sta++ = SMLAWB( sta[1], real, A ); /* index=314...........4 */ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=314...........4 */
*sta++ = SMULWB( imag, B ); /* index=10..........320 */ sta[0] = SMULWB( imag, B ); sta++; /* index=10..........320 */
*pMyTimeOut++ = result; pMyTimeOut[0] = result; pMyTimeOut++;
p_fltm -= 5; p_fltm -= 5;
p_flt += 5; p_flt += 5;
@ -610,8 +610,8 @@ INT qmfSynPrototypeFirSlot2(
{ {
FIXP_DBL result1, result2; FIXP_DBL result1, result2;
result1 = *pMyTimeOut++; result1 = pMyTimeOut[0]; pMyTimeOut++;
result2 = *pMyTimeOut++; result2 = pMyTimeOut[0]; pMyTimeOut++;
result1 = fMult(result1,gain); result1 = fMult(result1,gain);
timeOut -= stride; timeOut -= stride;
@ -635,8 +635,8 @@ INT qmfSynPrototypeFirSlot2(
timeOut[0] = result2 << scale; timeOut[0] = result2 << scale;
#endif #endif
result1 = *pMyTimeOut++; result1 = pMyTimeOut[0]; pMyTimeOut++;
result2 = *pMyTimeOut++; result2 = pMyTimeOut[0]; pMyTimeOut++;
result1 = fMult(result1,gain); result1 = fMult(result1,gain);
timeOut -= stride; timeOut -= stride;
@ -666,8 +666,8 @@ INT qmfSynPrototypeFirSlot2(
for (no_channels>>=2; no_channels--;) for (no_channels>>=2; no_channels--;)
{ {
FIXP_DBL result1, result2; FIXP_DBL result1, result2;
result1 = *pMyTimeOut++; result1 = pMyTimeOut[0]; pMyTimeOut++;
result2 = *pMyTimeOut++; result2 = pMyTimeOut[0]; pMyTimeOut++;
timeOut -= stride; timeOut -= stride;
if (result1 < 0) result1 += add_neg; if (result1 < 0) result1 += add_neg;
if (result1 < max_neg) result1 = max_neg; if (result1 < max_neg) result1 = max_neg;
@ -688,8 +688,8 @@ INT qmfSynPrototypeFirSlot2(
timeOut[0] = result2 << scale; timeOut[0] = result2 << scale;
#endif #endif
result1 = *pMyTimeOut++; result1 = pMyTimeOut[0]; pMyTimeOut++;
result2 = *pMyTimeOut++; result2 = pMyTimeOut[0]; pMyTimeOut++;
timeOut -= stride; timeOut -= stride;
if (result1 < 0) result1 += add_neg; if (result1 < 0) result1 += add_neg;
if (result1 < max_neg) result1 = max_neg; if (result1 < max_neg) result1 = max_neg;

View File

@ -324,12 +324,12 @@ void dct_IV(FIXP_DBL *pDat,
{ {
FIXP_DBL *RESTRICT pDat_0 = &pDat[0]; FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2]; FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
register int i; int i;
/* 29 cycles on ARM926 */ /* 29 cycles on ARM926 */
for (i = 0; i < M-1; i+=2,pDat_0+=2,pDat_1-=2) for (i = 0; i < M-1; i+=2,pDat_0+=2,pDat_1-=2)
{ {
register FIXP_DBL accu1,accu2,accu3,accu4; FIXP_DBL accu1,accu2,accu3,accu4;
accu1 = pDat_1[1]; accu2 = pDat_0[0]; accu1 = pDat_1[1]; accu2 = pDat_0[0];
accu3 = pDat_0[1]; accu4 = pDat_1[0]; accu3 = pDat_0[1]; accu4 = pDat_1[0];
@ -342,7 +342,7 @@ void dct_IV(FIXP_DBL *pDat,
} }
if (M&1) if (M&1)
{ {
register FIXP_DBL accu1,accu2; FIXP_DBL accu1,accu2;
accu1 = pDat_1[1]; accu2 = pDat_0[0]; accu1 = pDat_1[1]; accu2 = pDat_0[0];
@ -363,7 +363,7 @@ void dct_IV(FIXP_DBL *pDat,
{ {
FIXP_DBL *RESTRICT pDat_0 = &pDat[0]; FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2]; FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
register FIXP_DBL accu1,accu2,accu3,accu4; FIXP_DBL accu1,accu2,accu3,accu4;
int idx, i; int idx, i;
/* Sin and Cos values are 0.0f and 1.0f */ /* Sin and Cos values are 0.0f and 1.0f */
@ -450,12 +450,12 @@ void dst_IV(FIXP_DBL *pDat,
FIXP_DBL *RESTRICT pDat_0 = &pDat[0]; FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2]; FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
register int i; int i;
/* 34 cycles on ARM926 */ /* 34 cycles on ARM926 */
for (i = 0; i < M-1; i+=2,pDat_0+=2,pDat_1-=2) for (i = 0; i < M-1; i+=2,pDat_0+=2,pDat_1-=2)
{ {
register FIXP_DBL accu1,accu2,accu3,accu4; FIXP_DBL accu1,accu2,accu3,accu4;
accu1 = pDat_1[1]; accu2 = -pDat_0[0]; accu1 = pDat_1[1]; accu2 = -pDat_0[0];
accu3 = pDat_0[1]; accu4 = -pDat_1[0]; accu3 = pDat_0[1]; accu4 = -pDat_1[0];
@ -468,7 +468,7 @@ void dst_IV(FIXP_DBL *pDat,
} }
if (M&1) if (M&1)
{ {
register FIXP_DBL accu1,accu2; FIXP_DBL accu1,accu2;
accu1 = pDat_1[1]; accu2 = -pDat_0[0]; accu1 = pDat_1[1]; accu2 = -pDat_0[0];
@ -488,7 +488,7 @@ void dst_IV(FIXP_DBL *pDat,
{ {
FIXP_DBL *RESTRICT pDat_0; FIXP_DBL *RESTRICT pDat_0;
FIXP_DBL *RESTRICT pDat_1; FIXP_DBL *RESTRICT pDat_1;
register FIXP_DBL accu1,accu2,accu3,accu4; FIXP_DBL accu1,accu2,accu3,accu4;
int idx, i; int idx, i;
pDat_0 = &pDat[0]; pDat_0 = &pDat[0];

View File

@ -322,31 +322,31 @@ LNK_SECTION_CODE_L1 FIXP_DBL CalcInvLdData(FIXP_DBL x)
LNK_SECTION_CONSTDATA_L1 LNK_SECTION_CONSTDATA_L1
static const FIXP_DBL ldIntCoeff[] = { static const FIXP_DBL ldIntCoeff[] = {
0x80000001, 0x00000000, 0x02000000, 0x032b8034, 0x04000000, 0x04a4d3c2, 0x052b8034, 0x059d5da0, (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000, (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2, (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0,
0x06000000, 0x06570069, 0x06a4d3c2, 0x06eb3a9f, 0x072b8034, 0x0766a009, 0x079d5da0, 0x07d053f7, (FIXP_DBL)0x06000000, (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f, (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0, (FIXP_DBL)0x07d053f7,
0x08000000, 0x082cc7ee, 0x08570069, 0x087ef05b, 0x08a4d3c2, 0x08c8ddd4, 0x08eb3a9f, 0x090c1050, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee, (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2, (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
0x092b8034, 0x0949a785, 0x0966a009, 0x0982809d, 0x099d5da0, 0x09b74949, 0x09d053f7, 0x09e88c6b, (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009, (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949, (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b,
0x0a000000, 0x0a16bad3, 0x0a2cc7ee, 0x0a423162, 0x0a570069, 0x0a6b3d79, 0x0a7ef05b, 0x0a92203d, (FIXP_DBL)0x0a000000, (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162, (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b, (FIXP_DBL)0x0a92203d,
0x0aa4d3c2, 0x0ab7110e, 0x0ac8ddd4, 0x0ada3f60, 0x0aeb3a9f, 0x0afbd42b, 0x0b0c1050, 0x0b1bf312, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e, (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f, (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
0x0b2b8034, 0x0b3abb40, 0x0b49a785, 0x0b584822, 0x0b66a009, 0x0b74b1fd, 0x0b82809d, 0x0b900e61, (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785, (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd, (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61,
0x0b9d5da0, 0x0baa708f, 0x0bb74949, 0x0bc3e9ca, 0x0bd053f7, 0x0bdc899b, 0x0be88c6b, 0x0bf45e09, (FIXP_DBL)0x0b9d5da0, (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca, (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b, (FIXP_DBL)0x0bf45e09,
0x0c000000, 0x0c0b73cb, 0x0c16bad3, 0x0c21d671, 0x0c2cc7ee, 0x0c379085, 0x0c423162, 0x0c4caba8, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb, (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee, (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
0x0c570069, 0x0c6130af, 0x0c6b3d79, 0x0c7527b9, 0x0c7ef05b, 0x0c88983f, 0x0c92203d, 0x0c9b8926, (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79, (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f, (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926,
0x0ca4d3c2, 0x0cae00d2, 0x0cb7110e, 0x0cc0052b, 0x0cc8ddd4, 0x0cd19bb0, 0x0cda3f60, 0x0ce2c97d, (FIXP_DBL)0x0ca4d3c2, (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b, (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60, (FIXP_DBL)0x0ce2c97d,
0x0ceb3a9f, 0x0cf39355, 0x0cfbd42b, 0x0d03fda9, 0x0d0c1050, 0x0d140ca0, 0x0d1bf312, 0x0d23c41d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355, (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050, (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
0x0d2b8034, 0x0d3327c7, 0x0d3abb40, 0x0d423b08, 0x0d49a785, 0x0d510118, 0x0d584822, 0x0d5f7cff, (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40, (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118, (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff,
0x0d66a009, 0x0d6db197, 0x0d74b1fd, 0x0d7ba190, 0x0d82809d, 0x0d894f75, 0x0d900e61, 0x0d96bdad, (FIXP_DBL)0x0d66a009, (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190, (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61, (FIXP_DBL)0x0d96bdad,
0x0d9d5da0, 0x0da3ee7f, 0x0daa708f, 0x0db0e412, 0x0db74949, 0x0dbda072, 0x0dc3e9ca, 0x0dca258e, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f, (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949, (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e,
0x0dd053f7, 0x0dd6753e, 0x0ddc899b, 0x0de29143, 0x0de88c6b, 0x0dee7b47, 0x0df45e09, 0x0dfa34e1, (FIXP_DBL)0x0dd053f7, (FIXP_DBL)0x0dd6753e, (FIXP_DBL)0x0ddc899b, (FIXP_DBL)0x0de29143, (FIXP_DBL)0x0de88c6b, (FIXP_DBL)0x0dee7b47, (FIXP_DBL)0x0df45e09, (FIXP_DBL)0x0dfa34e1,
0x0e000000, 0x0e05bf94, 0x0e0b73cb, 0x0e111cd2, 0x0e16bad3, 0x0e1c4dfb, 0x0e21d671, 0x0e275460, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x0e05bf94, (FIXP_DBL)0x0e0b73cb, (FIXP_DBL)0x0e111cd2, (FIXP_DBL)0x0e16bad3, (FIXP_DBL)0x0e1c4dfb, (FIXP_DBL)0x0e21d671, (FIXP_DBL)0x0e275460,
0x0e2cc7ee, 0x0e323143, 0x0e379085, 0x0e3ce5d8, 0x0e423162, 0x0e477346, 0x0e4caba8, 0x0e51daa8, (FIXP_DBL)0x0e2cc7ee, (FIXP_DBL)0x0e323143, (FIXP_DBL)0x0e379085, (FIXP_DBL)0x0e3ce5d8, (FIXP_DBL)0x0e423162, (FIXP_DBL)0x0e477346, (FIXP_DBL)0x0e4caba8, (FIXP_DBL)0x0e51daa8,
0x0e570069, 0x0e5c1d0b, 0x0e6130af, 0x0e663b74, 0x0e6b3d79, 0x0e7036db, 0x0e7527b9, 0x0e7a1030, (FIXP_DBL)0x0e570069, (FIXP_DBL)0x0e5c1d0b, (FIXP_DBL)0x0e6130af, (FIXP_DBL)0x0e663b74, (FIXP_DBL)0x0e6b3d79, (FIXP_DBL)0x0e7036db, (FIXP_DBL)0x0e7527b9, (FIXP_DBL)0x0e7a1030,
0x0e7ef05b, 0x0e83c857, 0x0e88983f, 0x0e8d602e, 0x0e92203d, 0x0e96d888, 0x0e9b8926, 0x0ea03232, (FIXP_DBL)0x0e7ef05b, (FIXP_DBL)0x0e83c857, (FIXP_DBL)0x0e88983f, (FIXP_DBL)0x0e8d602e, (FIXP_DBL)0x0e92203d, (FIXP_DBL)0x0e96d888, (FIXP_DBL)0x0e9b8926, (FIXP_DBL)0x0ea03232,
0x0ea4d3c2, 0x0ea96df0, 0x0eae00d2, 0x0eb28c7f, 0x0eb7110e, 0x0ebb8e96, 0x0ec0052b, 0x0ec474e4, (FIXP_DBL)0x0ea4d3c2, (FIXP_DBL)0x0ea96df0, (FIXP_DBL)0x0eae00d2, (FIXP_DBL)0x0eb28c7f, (FIXP_DBL)0x0eb7110e, (FIXP_DBL)0x0ebb8e96, (FIXP_DBL)0x0ec0052b, (FIXP_DBL)0x0ec474e4,
0x0ec8ddd4, 0x0ecd4012, 0x0ed19bb0, 0x0ed5f0c4, 0x0eda3f60, 0x0ede8797, 0x0ee2c97d, 0x0ee70525, (FIXP_DBL)0x0ec8ddd4, (FIXP_DBL)0x0ecd4012, (FIXP_DBL)0x0ed19bb0, (FIXP_DBL)0x0ed5f0c4, (FIXP_DBL)0x0eda3f60, (FIXP_DBL)0x0ede8797, (FIXP_DBL)0x0ee2c97d, (FIXP_DBL)0x0ee70525,
0x0eeb3a9f, 0x0eef69ff, 0x0ef39355, 0x0ef7b6b4, 0x0efbd42b, 0x0effebcd, 0x0f03fda9, 0x0f0809cf, (FIXP_DBL)0x0eeb3a9f, (FIXP_DBL)0x0eef69ff, (FIXP_DBL)0x0ef39355, (FIXP_DBL)0x0ef7b6b4, (FIXP_DBL)0x0efbd42b, (FIXP_DBL)0x0effebcd, (FIXP_DBL)0x0f03fda9, (FIXP_DBL)0x0f0809cf,
0x0f0c1050, 0x0f10113b, 0x0f140ca0, 0x0f18028d, 0x0f1bf312, 0x0f1fde3d, 0x0f23c41d, 0x0f27a4c0, (FIXP_DBL)0x0f0c1050, (FIXP_DBL)0x0f10113b, (FIXP_DBL)0x0f140ca0, (FIXP_DBL)0x0f18028d, (FIXP_DBL)0x0f1bf312, (FIXP_DBL)0x0f1fde3d, (FIXP_DBL)0x0f23c41d, (FIXP_DBL)0x0f27a4c0,
0x0f2b8034 (FIXP_DBL)0x0f2b8034
}; };

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -449,13 +449,13 @@ void CProgramConfig_GetDefault( CProgramConfig *pPce,
int el, elTagSce = 0, elTagCpe = 0; int el, elTagSce = 0, elTagCpe = 0;
for (el = 0; el < pPce->NumFrontChannelElements; el += 1) { for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
pPce->FrontElementTagSelect[el] = (pPce->FrontElementIsCpe) ? elTagCpe++ : elTagSce++; pPce->FrontElementTagSelect[el] = (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
} }
for (el = 0; el < pPce->NumSideChannelElements; el += 1) { for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
pPce->SideElementTagSelect[el] = (pPce->SideElementIsCpe) ? elTagCpe++ : elTagSce++; pPce->SideElementTagSelect[el] = (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
} }
for (el = 0; el < pPce->NumBackChannelElements; el += 1) { for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
pPce->BackElementTagSelect[el] = (pPce->BackElementIsCpe) ? elTagCpe++ : elTagSce++; pPce->BackElementTagSelect[el] = (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
} }
elTagSce = 0; elTagSce = 0;
for (el = 0; el < pPce->NumLfeChannelElements; el += 1) { for (el = 0; el < pPce->NumLfeChannelElements; el += 1) {
@ -1126,6 +1126,8 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
if ( 0 != ld_sbr_header(asc, hBs, cb) ) { if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
return TRANSPORTDEC_PARSE_ERROR; return TRANSPORTDEC_PARSE_ERROR;
} }
} else {
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
} }
} }
esc->m_useLdQmfTimeAlign = 0; esc->m_useLdQmfTimeAlign = 0;
@ -1146,7 +1148,7 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
switch (eldExtType) { switch (eldExtType) {
default: default:
for(cnt=0; cnt<len; cnt++) { for(cnt=0; cnt<eldExtLen; cnt++) {
FDKreadBits(hBs, 8 ); FDKreadBits(hBs, 8 );
} }
break; break;
@ -1372,4 +1374,133 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
return (ErrorStatus); return (ErrorStatus);
} }
TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
CSAudioSpecificConfig *self,
HANDLE_FDK_BITSTREAM bs
)
{
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
AudioSpecificConfig_Init(self);
if ((INT)FDKgetValidBits(bs) < 20) {
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
goto bail;
}
else {
/* DRM - Audio information data entity - type 9
- Short Id 2 bits
- Stream Id 2 bits
- audio coding 2 bits
- SBR flag 1 bit
- audio mode 2 bits
- audio sampling rate 3 bits
- text flag 1 bit
- enhancement flag 1 bit
- coder field 5 bits
- rfa 1 bit */
int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;
/* Read the SDC field */
FDKreadBits(bs,4); /* Short and Stream Id */
audioCoding = FDKreadBits(bs, 2);
sbrFlag = FDKreadBits(bs, 1);
audioMode = FDKreadBits(bs, 2);
cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */
FDKreadBits(bs, 2); /* Text and enhancement flag */
coderField = FDKreadBits(bs, 5);
FDKreadBits(bs, 1); /* rfa */
/* Evaluate configuration and fill the ASC */
switch (cSamplingFreq) {
case 0: /* 8 kHz */
sfIdx = 11;
break;
case 1: /* 12 kHz */
sfIdx = 9;
break;
case 2: /* 16 kHz */
sfIdx = 8;
break;
case 3: /* 24 kHz */
sfIdx = 6;
break;
case 5: /* 48 kHz */
sfIdx = 3;
break;
case 4: /* reserved */
case 6: /* reserved */
case 7: /* reserved */
default:
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
goto bail;
}
self->m_samplingFrequencyIndex = sfIdx;
self->m_samplingFrequency = SamplingRateTable[sfIdx];
if ( sbrFlag ) {
UINT i;
int tmp = -1;
self->m_sbrPresentFlag = 1;
self->m_extensionAudioObjectType = AOT_SBR;
self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){
if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){
tmp = i;
break;
}
}
self->m_extensionSamplingFrequencyIndex = tmp;
}
switch (audioCoding) {
case 0: /* AAC */
self->m_aot = AOT_DRM_AAC ; /* Set pseudo AOT for Drm AAC */
switch (audioMode) {
case 1: /* parametric stereo */
self->m_psPresentFlag = 1;
case 0: /* mono */
self->m_channelConfiguration = 1;
break;
case 2: /* stereo */
self->m_channelConfiguration = 2;
break;
default:
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
goto bail;
}
self->m_vcb11Flag = 1;
self->m_hcrFlag = 1;
self->m_samplesPerFrame = 960;
self->m_epConfig = 1;
break;
case 1: /* CELP */
self->m_aot = AOT_ER_CELP;
self->m_channelConfiguration = 1;
break;
case 2: /* HVXC */
self->m_aot = AOT_ER_HVXC;
self->m_channelConfiguration = 1;
break;
case 3: /* reserved */
default:
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
self->m_aot = AOT_NONE;
break;
}
if (self->m_psPresentFlag && !self->m_sbrPresentFlag) {
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
goto bail;
}
}
bail:
return (ErrorStatus);
}

View File

@ -0,0 +1,146 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2015 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
----------------------------------------------------------------------------------------------------------- */
/***************************** MPEG-4 AAC Decoder **************************
Author(s): Christian Griebel
Description: DRM transport stuff
******************************************************************************/
#include "tpdec_drm.h"
#include "FDK_bitstream.h"
void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */
{
FDK_ASSERT(pDrm != NULL);
FDKcrcInit(&pDrm->crcInfo, 0x001d, 0xFFFF, 8);
}
int drmRead_CrcStartReg(
HANDLE_DRM pDrm, /*!< pointer to drm stucture */
HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
int mBits /*!< number of bits in crc region */
)
{
FDK_ASSERT(pDrm != NULL);
FDKcrcReset(&pDrm->crcInfo);
pDrm->crcReadValue = FDKreadBits(hBs, 8);
return ( FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits) );
}
void drmRead_CrcEndReg(
HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */
HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
int reg /*!< crc region */
)
{
FDK_ASSERT(pDrm != NULL);
FDKcrcEndReg(&pDrm->crcInfo, hBs, reg);
}
TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm )
{
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
USHORT crc;
crc = FDKcrcGetCRC(&pDrm->crcInfo) ^ 0xFF;
if (crc != pDrm->crcReadValue)
{
return (TRANSPORTDEC_CRC_ERROR);
}
return (ErrorStatus);
}

View File

@ -0,0 +1,194 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2015 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
----------------------------------------------------------------------------------------------------------- */
/***************************** MPEG-4 AAC Decoder **************************
Author(s): Josef Hoepfl
Description: DRM interface
******************************************************************************/
#ifndef TPDEC_DRM_H
#define TPDEC_DRM_H
#include "tpdec_lib.h"
#include "FDK_crc.h"
typedef struct {
FDK_CRCINFO crcInfo; /* CRC state info */
USHORT crcReadValue; /* CRC value read from bitstream data */
} STRUCT_DRM;
typedef STRUCT_DRM *HANDLE_DRM;
/*!
\brief Initialize DRM CRC
The function initialzes the crc buffer and the crc lookup table.
\return none
*/
void drmRead_CrcInit( HANDLE_DRM pDrm );
/**
* \brief Starts CRC region with a maximum number of bits
* If mBits is positive zero padding will be used for CRC calculation, if there
* are less than mBits bits available.
* If mBits is negative no zero padding is done.
* If mBits is zero the memory for the buffer is allocated dynamically, the
* number of bits is not limited.
*
* \param pDrm DRM data handle
* \param hBs bitstream handle, on which the CRC region referes to
* \param mBits max number of bits in crc region to be considered
*
* \return ID for the created region, -1 in case of an error
*/
int drmRead_CrcStartReg(
HANDLE_DRM pDrm,
HANDLE_FDK_BITSTREAM hBs,
int mBits
);
/**
* \brief Ends CRC region identified by reg
*
* \param pDrm DRM data handle
* \param hBs bitstream handle, on which the CRC region referes to
* \param reg CRC regions ID returned by drmRead_CrcStartReg()
*
* \return none
*/
void drmRead_CrcEndReg(
HANDLE_DRM pDrm,
HANDLE_FDK_BITSTREAM hBs,
int reg
);
/**
* \brief Check CRC
*
* Checks if the currently calculated CRC matches the CRC field read from the bitstream
* Deletes all CRC regions.
*
* \param pDrm DRM data handle
*
* \return Returns 0 if they are identical otherwise 1
*/
TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm );
/**
* \brief Check if we have a valid DRM frame at the current bitbuffer position
*
* This function assumes enough bits in buffer for the current frame.
* It reads out the header bits to prepare the bitbuffer for the decode loop.
* In case the header bits show an invalid bitstream/frame, the whole frame is skipped.
*
* \param pDrm DRM data handle which is filled with parsed DRM header data
* \param bs handle of bitstream from whom the DRM header is read
*
* \return error status
*/
TRANSPORTDEC_ERROR drmRead_DecodeHeader(
HANDLE_DRM pDrm,
HANDLE_FDK_BITSTREAM bs
);
/**
* \brief Parse a Drm specific SDC audio config from a given bitstream handle.
*
* \param pAsc A pointer to an allocated CSAudioSpecificConfig struct.
* \param hBs Bitstream handle.
*
* \return Total element count including all SCE, CPE and LFE.
*/
TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *pAsc,
HANDLE_FDK_BITSTREAM hBs );
#endif /* TPDEC_DRM_H */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -102,6 +102,7 @@ amm-info@iis.fraunhofer.de
#include "tpdec_latm.h" #include "tpdec_latm.h"
#include "tpdec_drm.h"
#define MODULE_NAME "transportDec" #define MODULE_NAME "transportDec"
@ -113,6 +114,7 @@ typedef union {
CLatmDemux latm; CLatmDemux latm;
STRUCT_DRM drm;
} transportdec_parser_t; } transportdec_parser_t;
@ -182,6 +184,9 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const
hInput->numberOfRawDataBlocks = 0; hInput->numberOfRawDataBlocks = 0;
break; break;
case TT_DRM:
drmRead_CrcInit(&hInput->parser.drm);
break;
case TT_MP4_LATM_MCP0: case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1: case TT_MP4_LATM_MCP1:
@ -253,6 +258,18 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *
} }
} }
break; break;
case TT_DRM:
fConfigFound = 1;
err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs);
if (err == TRANSPORTDEC_OK) {
int errC;
errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
if (errC != 0) {
err = TRANSPORTDEC_PARSE_ERROR;
}
}
break;
} }
if (err == TRANSPORTDEC_OK && fConfigFound) { if (err == TRANSPORTDEC_OK && fConfigFound) {
@ -1083,6 +1100,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
break; break;
case TT_MP4_RAW: case TT_MP4_RAW:
case TT_DRM:
/* One Access Unit was filled into buffer. /* One Access Unit was filled into buffer.
So get the length out of the buffer. */ So get the length out of the buffer. */
hTp->auLength[layer] = FDKgetValidBits(hBs); hTp->auLength[layer] = FDKgetValidBits(hBs);
@ -1100,7 +1118,6 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
} }
break; break;
case TT_RSVD50:
case TT_MP4_ADTS: case TT_MP4_ADTS:
case TT_MP4_LOAS: case TT_MP4_LOAS:
err = transportDec_readStream(hTp, layer); err = transportDec_readStream(hTp, layer);
@ -1268,8 +1285,13 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
info += i; info += i;
info->module_id = FDK_TPDEC; info->module_id = FDK_TPDEC;
#ifdef __ANDROID__
info->build_date = "";
info->build_time = "";
#else
info->build_date = __DATE__; info->build_date = __DATE__;
info->build_time = __TIME__; info->build_time = __TIME__;
#endif
info->title = TP_LIB_TITLE; info->title = TP_LIB_TITLE;
info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2); info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
LIB_VERSION_STRING(info); LIB_VERSION_STRING(info);
@ -1279,6 +1301,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
| CAPF_LATM | CAPF_LATM
| CAPF_LOAS | CAPF_LOAS
| CAPF_RAWPACKETS | CAPF_RAWPACKETS
| CAPF_DRM
; ;
return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */ return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
@ -1290,6 +1313,8 @@ int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits)
switch (pTp->transportFmt) { switch (pTp->transportFmt) {
case TT_MP4_ADTS: case TT_MP4_ADTS:
return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits); return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
case TT_DRM:
return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
default: default:
return 0; return 0;
} }
@ -1301,6 +1326,9 @@ void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg)
case TT_MP4_ADTS: case TT_MP4_ADTS:
adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg); adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
break; break;
case TT_DRM:
drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
break;
default: default:
break; break;
} }
@ -1317,6 +1345,9 @@ TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)
transportDec_AdjustEndOfAccessUnit(pTp); transportDec_AdjustEndOfAccessUnit(pTp);
} }
return adtsRead_CrcCheck(&pTp->parser.adts); return adtsRead_CrcCheck(&pTp->parser.adts);
case TT_DRM:
return drmRead_CrcCheck(&pTp->parser.drm);
break;
default: default:
return TRANSPORTDEC_OK; return TRANSPORTDEC_OK;
} }

View File

@ -2,7 +2,12 @@
/* library info */ /* library info */
#define TP_LIB_VL0 2 #define TP_LIB_VL0 2
#define TP_LIB_VL1 3 #define TP_LIB_VL1 3
#define TP_LIB_VL2 4 #define TP_LIB_VL2 7
#define TP_LIB_TITLE "MPEG Transport" #define TP_LIB_TITLE "MPEG Transport"
#ifdef __ANDROID__
#define TP_LIB_BUILD_DATE ""
#define TP_LIB_BUILD_TIME ""
#else
#define TP_LIB_BUILD_DATE __DATE__ #define TP_LIB_BUILD_DATE __DATE__
#define TP_LIB_BUILD_TIME __TIME__ #define TP_LIB_BUILD_TIME __TIME__
#endif

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -296,6 +296,7 @@ CreateStreamMuxConfig(
USHORT coreFrameOffset=0; USHORT coreFrameOffset=0;
hAss->taraBufferFullness = 0xFF;
hAss->audioMuxVersionA = 0; /* for future extensions */ hAss->audioMuxVersionA = 0; /* for future extensions */
hAss->streamMuxConfigBits = 0; hAss->streamMuxConfigBits = 0;
@ -339,13 +340,7 @@ CreateStreamMuxConfig(
hAss->streamMuxConfigBits+=1; hAss->streamMuxConfigBits+=1;
} }
if( (useSameConfig == 0) || (transLayer==0) ) { if( (useSameConfig == 0) || (transLayer==0) ) {
UINT bits; const UINT alignAnchor = FDKgetValidBits(hBs);
if ( hAss->audioMuxVersion == 1 ) {
FDKpushFor(hBs, 2); /* align to ASC, even if we do not know the length of the "ascLen" field yet */
}
bits = FDKgetValidBits( hBs );
transportEnc_writeASC( transportEnc_writeASC(
hBs, hBs,
@ -353,19 +348,24 @@ CreateStreamMuxConfig(
cb cb
); );
bits = FDKgetValidBits( hBs ) - bits;
if ( hAss->audioMuxVersion == 1 ) { if ( hAss->audioMuxVersion == 1 ) {
FDKpushBack(hBs, bits+2); UINT ascLen = transportEnc_LatmWriteValue(hBs, 0);
hAss->streamMuxConfigBits += transportEnc_LatmWriteValue( hBs, bits ); FDKbyteAlign(hBs, alignAnchor);
ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen;
FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor);
transportEnc_LatmWriteValue(hBs, ascLen);
transportEnc_writeASC( transportEnc_writeASC(
hBs, hBs,
hAss->config[prog][layer], hAss->config[prog][layer],
cb cb
); );
FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */
} }
hAss->streamMuxConfigBits += bits; /* add asc length to smc summary */ hAss->streamMuxConfigBits += FDKgetValidBits(hBs) - alignAnchor; /* add asc length to smc summary */
} }
transLayer++; transLayer++;
@ -384,7 +384,6 @@ CreateStreamMuxConfig(
case AOT_ER_AAC_LD : case AOT_ER_AAC_LD :
case AOT_ER_AAC_ELD : case AOT_ER_AAC_ELD :
case AOT_USAC: case AOT_USAC:
case AOT_RSVD50:
p_linfo->frameLengthType = 0; p_linfo->frameLengthType = 0;
FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */ FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */

View File

@ -619,8 +619,13 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo( LIB_INFO *info )
info->module_id = FDK_TPENC; info->module_id = FDK_TPENC;
info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2); info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
LIB_VERSION_STRING(info); LIB_VERSION_STRING(info);
#ifdef __ANDROID__
info->build_date = "";
info->build_time = "";
#else
info->build_date = __DATE__; info->build_date = __DATE__;
info->build_time = __TIME__; info->build_time = __TIME__;
#endif
info->title = TP_LIB_TITLE; info->title = TP_LIB_TITLE;
/* Set flags */ /* Set flags */

View File

@ -2,7 +2,12 @@
/* library info */ /* library info */
#define TP_LIB_VL0 2 #define TP_LIB_VL0 2
#define TP_LIB_VL1 3 #define TP_LIB_VL1 3
#define TP_LIB_VL2 4 #define TP_LIB_VL2 6
#define TP_LIB_TITLE "MPEG Transport" #define TP_LIB_TITLE "MPEG Transport"
#ifdef __ANDROID__
#define TP_LIB_BUILD_DATE ""
#define TP_LIB_BUILD_TIME ""
#else
#define TP_LIB_BUILD_DATE __DATE__ #define TP_LIB_BUILD_DATE __DATE__
#define TP_LIB_BUILD_TIME __TIME__ #define TP_LIB_BUILD_TIME __TIME__
#endif

View File

@ -150,8 +150,13 @@ amm-info@iis.fraunhofer.de
#define PCMDMX_LIB_VL1 4 #define PCMDMX_LIB_VL1 4
#define PCMDMX_LIB_VL2 2 #define PCMDMX_LIB_VL2 2
#define PCMDMX_LIB_TITLE "PCM Downmix Lib" #define PCMDMX_LIB_TITLE "PCM Downmix Lib"
#ifdef __ANDROID__
#define PCMDMX_LIB_BUILD_DATE ""
#define PCMDMX_LIB_BUILD_TIME ""
#else
#define PCMDMX_LIB_BUILD_DATE __DATE__ #define PCMDMX_LIB_BUILD_DATE __DATE__
#define PCMDMX_LIB_BUILD_TIME __TIME__ #define PCMDMX_LIB_BUILD_TIME __TIME__
#endif
/* Fixed and unique channel group indices. /* Fixed and unique channel group indices.
@ -2073,7 +2078,9 @@ PCMDMX_ERROR pcmDmx_ApplyFrame (
map[ch++] = inCh; map[ch++] = inCh;
} }
} }
FDK_ASSERT(ch == numInChannels); if (ch != numInChannels) {
return PCMDMX_INVALID_ARGUMENT;
}
/* Remove unused cols from factor matrix */ /* Remove unused cols from factor matrix */
for (inCh=0; inCh < numInChannels; inCh+=1) { for (inCh=0; inCh < numInChannels; inCh+=1) {

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -262,6 +262,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self,
* into *count if a payload length is given (byPayLen > 0). If no SBR payload length is * into *count if a payload length is given (byPayLen > 0). If no SBR payload length is
* given (bsPayLen < 0) then the bit stream position on return will be random after this * given (bsPayLen < 0) then the bit stream position on return will be random after this
* function call in case of errors, and any further decoding will be completely pointless. * function call in case of errors, and any further decoding will be completely pointless.
* This function accepts either normal ordered SBR data or reverse ordered DRM SBR data.
* *
* \param self SBR decoder handle. * \param self SBR decoder handle.
* \param hBs Bit stream handle as data source. * \param hBs Bit stream handle as data source.

View File

@ -97,7 +97,10 @@ amm-info@iis.fraunhofer.de
#ifdef FUNCTION_LPPTRANSPOSER_func1 #ifdef FUNCTION_LPPTRANSPOSER_func1
/* Note: This code requires only 43 cycles per iteration instead of 61 on ARM926EJ-S */ /* 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 *lowBandReal,
FIXP_DBL *lowBandImag, FIXP_DBL *lowBandImag,
FIXP_DBL **qmfBufferReal, FIXP_DBL **qmfBufferReal,

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -151,13 +151,13 @@ typedef struct
} }
ENV_CALC_NRGS; ENV_CALC_NRGS;
/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
SCHAR *filtBuffer_e, SCHAR *filtBuffer_e,
FIXP_DBL *NrgGain, FIXP_DBL *NrgGain,
SCHAR *NrgGain_e, SCHAR *NrgGain_e,
int subbands); int subbands);
/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, static void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
FIXP_DBL **analysBufferImag, FIXP_DBL **analysBufferImag,
int lowSubband, int highSubband, int lowSubband, int highSubband,
int start_pos, int next_pos, int start_pos, int next_pos,
@ -165,7 +165,7 @@ ENV_CALC_NRGS;
FIXP_DBL *nrgEst, FIXP_DBL *nrgEst,
SCHAR *nrgEst_e ); SCHAR *nrgEst_e );
/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, static void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
FIXP_DBL **analysBufferImag, FIXP_DBL **analysBufferImag,
int nSfb, int nSfb,
UCHAR *freqBandTable, UCHAR *freqBandTable,
@ -174,13 +174,13 @@ ENV_CALC_NRGS;
FIXP_DBL *nrg_est, FIXP_DBL *nrg_est,
SCHAR *nrg_est_e ); SCHAR *nrg_est_e );
/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c, static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
FIXP_DBL tmpNoise, SCHAR tmpNoise_e, FIXP_DBL tmpNoise, SCHAR tmpNoise_e,
UCHAR sinePresentFlag, UCHAR sinePresentFlag,
UCHAR sineMapped, UCHAR sineMapped,
int noNoiseFlag); int noNoiseFlag);
/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, static void calcAvgGain(ENV_CALC_NRGS* nrgs,
int lowSubband, int lowSubband,
int highSubband, int highSubband,
FIXP_DBL *sumRef_m, FIXP_DBL *sumRef_m,
@ -188,7 +188,7 @@ ENV_CALC_NRGS;
FIXP_DBL *ptrAvgGain_m, FIXP_DBL *ptrAvgGain_m,
SCHAR *ptrAvgGain_e); SCHAR *ptrAvgGain_e);
/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal,
ENV_CALC_NRGS* nrgs, ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex, UCHAR *ptrHarmIndex,
int lowSubbands, int lowSubbands,
@ -196,8 +196,17 @@ ENV_CALC_NRGS;
int scale_change, int scale_change,
int noNoiseFlag, int noNoiseFlag,
int *ptrPhaseIndex, int *ptrPhaseIndex,
int fCldfb); int scale_diff_low);
/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
static void adjustTimeSlotLC(FIXP_DBL *ptrReal,
ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex,
int lowSubbands,
int noSubbands,
int scale_change,
int noNoiseFlag,
int *ptrPhaseIndex);
static void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
FIXP_DBL *ptrImag, FIXP_DBL *ptrImag,
HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
ENV_CALC_NRGS* nrgs, ENV_CALC_NRGS* nrgs,
@ -224,7 +233,7 @@ ENV_CALC_NRGS;
Additionally, the flags in harmFlagsPrev are being updated by this function Additionally, the flags in harmFlagsPrev are being updated by this function
for the next frame. for the next frame.
*/ */
/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ static void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
int nSfb, /*!< Number of bands in the table */ int nSfb, /*!< Number of bands in the table */
UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */ UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */
int *harmFlagsPrev, /*!< Packed 'addHarmonics' */ int *harmFlagsPrev, /*!< Packed 'addHarmonics' */
@ -990,7 +999,6 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
/* Prevent the smoothing filter from running on constant levels */ /* Prevent the smoothing filter from running on constant levels */
if (j-start_pos < smooth_length) if (j-start_pos < smooth_length)
smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos]; smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos];
else else
smooth_ratio = FL2FXCONST_SGL(0.0f); smooth_ratio = FL2FXCONST_SGL(0.0f);
@ -1007,7 +1015,8 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
} }
else else
{ {
adjustTimeSlotLC(&analysBufferReal[j][lowSubband], if (flags & SBRDEC_ELD_GRID) {
adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband],
pNrgs, pNrgs,
&h_sbr_cal_env->harmIndex, &h_sbr_cal_env->harmIndex,
lowSubband, lowSubband,
@ -1015,7 +1024,18 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
scale_change, scale_change,
noNoiseFlag, noNoiseFlag,
&h_sbr_cal_env->phaseIndex, &h_sbr_cal_env->phaseIndex,
(flags & SBRDEC_ELD_GRID)); EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
} else
{
adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
pNrgs,
&h_sbr_cal_env->harmIndex,
lowSubband,
noSubbands,
scale_change,
noNoiseFlag,
&h_sbr_cal_env->phaseIndex);
}
} }
} // for } // for
@ -1176,7 +1196,7 @@ resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to env
can be performed. can be performed.
This function is called once for each envelope before adjusting. This function is called once for each envelope before adjusting.
*/ */
/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */ SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
FIXP_DBL *nrgGain, /*!< gains for current envelope */ FIXP_DBL *nrgGain, /*!< gains for current envelope */
SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */ SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
@ -1331,7 +1351,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
This function is used when interpolFreq is true. This function is used when interpolFreq is true.
*/ */
/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
int lowSubband, /*!< Begin of the SBR frequency range */ int lowSubband, /*!< Begin of the SBR frequency range */
int highSubband, /*!< High end of the SBR frequency range */ int highSubband, /*!< High end of the SBR frequency range */
@ -1452,7 +1472,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
This function is used when interpolFreq is false. This function is used when interpolFreq is false.
*/ */
/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
int nSfb, /*!< Number of scale factor bands */ int nSfb, /*!< Number of scale factor bands */
UCHAR *freqBandTable, /*!< First Subband for each Sfb */ UCHAR *freqBandTable, /*!< First Subband for each Sfb */
@ -1585,7 +1605,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
The resulting energy gain is given by mantissa and exponent. The resulting energy gain is given by mantissa and exponent.
*/ */
/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ static void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */ SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
ENV_CALC_NRGS* nrgs, ENV_CALC_NRGS* nrgs,
int i, int i,
@ -1689,7 +1709,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
The result is used as a relative limit for all gains within the The result is used as a relative limit for all gains within the
current "limiter band" (a certain frequency range). current "limiter band" (a certain frequency range).
*/ */
/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, static void calcAvgGain(ENV_CALC_NRGS* nrgs,
int lowSubband, /*!< Begin of the limiter band */ int lowSubband, /*!< Begin of the limiter band */
int highSubband, /*!< High end of the limiter band */ int highSubband, /*!< High end of the limiter band */
FIXP_DBL *ptrSumRef, FIXP_DBL *ptrSumRef,
@ -1728,21 +1748,101 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
*ptrSumRef_e = sumRef_e; *ptrSumRef_e = sumRef_e;
} }
static void adjustTimeSlot_EldGrid(
FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex, /*!< Harmonic index */
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
int noSubbands, /*!< Number of QMF subbands */
int scale_change, /*!< Number of bits to shift adjusted samples */
int noNoiseFlag, /*!< Flag to suppress noise addition */
int *ptrPhaseIndex, /*!< Start index to random number array */
int scale_diff_low) /*!< */
{
int k;
FIXP_DBL signalReal, sbNoise;
int tone_count = 0;
FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
int phaseIndex = *ptrPhaseIndex;
UCHAR harmIndex = *ptrHarmIndex;
static const INT harmonicPhase [2][4] = {
{ 1, 0, -1, 0},
{ 0, 1, 0, -1}
};
static const FIXP_DBL harmonicPhaseX [2][4] = {
{ FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) },
{ FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) }
};
for (k=0; k < noSubbands; k++) {
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){
sbNoise = FL2FXCONST_DBL(0.0f);
} else {
sbNoise = pNoiseLevel[0];
}
signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4);
signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex];
*ptrReal = signalReal;
if (k == 0) {
*(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low) ;
if (k < noSubbands - 1) {
*(ptrReal) += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]);
}
}
if (k > 0 && k < noSubbands - 1 && tone_count < 16) {
*(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1] [harmIndex]);
*(ptrReal) += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]);
}
if (k == noSubbands - 1 && tone_count < 16) {
if (k > 0) {
*(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]);
}
if (k + lowSubband + 1< 63) {
*(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]);
}
}
if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){
tone_count++;
}
ptrReal++;
pNoiseLevel++;
pGain++;
pSineLevel++;
}
*ptrHarmIndex = (harmIndex + 1) & 3;
*ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
}
/*! /*!
\brief Amplify one timeslot of the signal with the calculated gains \brief Amplify one timeslot of the signal with the calculated gains
and add the noisefloor. and add the noisefloor.
*/ */
/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ static void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
ENV_CALC_NRGS* nrgs, ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex, /*!< Harmonic index */ UCHAR *ptrHarmIndex, /*!< Harmonic index */
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
int noSubbands, /*!< Number of QMF subbands */ int noSubbands, /*!< Number of QMF subbands */
int scale_change, /*!< Number of bits to shift adjusted samples */ int scale_change, /*!< Number of bits to shift adjusted samples */
int noNoiseFlag, /*!< Flag to suppress noise addition */ int noNoiseFlag, /*!< Flag to suppress noise addition */
int *ptrPhaseIndex, /*!< Start index to random number array */ int *ptrPhaseIndex) /*!< Start index to random number array */
int fCldfb) /*!< CLDFB 80 flag */
{ {
FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
@ -1775,41 +1875,10 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++; if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++;
else if (!noNoiseFlag) else if (!noNoiseFlag)
/* Add noisefloor to the amplified signal */ /* Add noisefloor to the amplified signal */
signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
if (fCldfb) {
if (!(harmIndex&0x1)) {
/* harmIndex 0,2 */
signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
*ptrReal++ = signalReal;
}
else {
/* harmIndex 1,3 in combination with freqInvFlag */
int shift = (int) (scale_change+1);
shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift );
FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext);
/* save switch and compare operations and reduce to XOR statement */
if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
*(ptrReal-1) += tmp1;
signalReal -= tmp2;
} else {
*(ptrReal-1) -= tmp1;
signalReal += tmp2;
}
*ptrReal++ = signalReal;
freqInvFlag = !freqInvFlag;
}
} else
{ {
if (!(harmIndex&0x1)) { if (!(harmIndex&0x1)) {
/* harmIndex 0,2 */ /* harmIndex 0,2 */
@ -1933,8 +2002,9 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
*ptrHarmIndex = (harmIndex + 1) & 3; *ptrHarmIndex = (harmIndex + 1) & 3;
*ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
} }
void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ static void adjustTimeSlotHQ(
FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
ENV_CALC_NRGS* nrgs, ENV_CALC_NRGS* nrgs,
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
@ -1961,7 +2031,7 @@ void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples
FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
int index = *ptrPhaseIndex; int index = *ptrPhaseIndex;
UCHAR harmIndex = *ptrHarmIndex; UCHAR harmIndex = *ptrHarmIndex;
register int freqInvFlag = (lowSubband & 1); int freqInvFlag = (lowSubband & 1);
FIXP_DBL sineLevel; FIXP_DBL sineLevel;
int shift; int shift;
@ -2137,7 +2207,6 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM
UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
int patchBorders[MAX_NUM_PATCHES + 1]; int patchBorders[MAX_NUM_PATCHES + 1];
int kx, k2; int kx, k2;
FIXP_DBL temp;
int lowSubband = freqBandTable[0]; int lowSubband = freqBandTable[0];
int highSubband = freqBandTable[noFreqBands]; int highSubband = freqBandTable[noFreqBands];
@ -2169,13 +2238,32 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM
while (hiLimIndex <= tempNoLim) { while (hiLimIndex <= tempNoLim) {
FIXP_DBL div_m, oct_m, temp;
INT div_e = 0, oct_e = 0, temp_e = 0;
k2 = workLimiterBandTable[hiLimIndex] + lowSubband; k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
kx = workLimiterBandTable[loLimIndex] + lowSubband; kx = workLimiterBandTable[loLimIndex] + lowSubband;
temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */ div_m = fDivNorm(k2, kx, &div_e);
temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]);
/* calculate number of octaves */
oct_m = fLog2(div_m, div_e, &oct_e);
/* multiply with limiterbands per octave */
/* values 1, 1.2, 2, 3 -> scale factor of 2 */
temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e);
/* overall scale factor of temp ist addition of scalefactors from log2 calculation,
limiter bands scalefactor (2) and limiter bands multiplication */
temp_e += oct_e + 2;
/* div can be a maximum of 64 (k2 = 64 and kx = 1)
-> oct can be a maximum of 6
-> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3)
-> we need a scale factor of 5 for comparisson
*/
if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) {
if (temp < FL2FXCONST_DBL (0.49f)>>5) {
if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) { if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) {
workLimiterBandTable[hiLimIndex] = highSubband; workLimiterBandTable[hiLimIndex] = highSubband;
nBands--; nBands--;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -369,7 +369,7 @@ leanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control d
FIXP_SGL step; /* speed of fade */ FIXP_SGL step; /* speed of fade */
int i; int i;
int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots; int currentStartPos = FDKmax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
int currentStopPos = hHeaderData->numberTimeSlots; int currentStopPos = hHeaderData->numberTimeSlots;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -327,7 +327,7 @@ sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData,
} }
/* Look for new settings. IEC 14496-3, 4.6.18.3.1 */ /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */
if(hHeaderData->syncState != SBR_ACTIVE || if(hHeaderData->syncState < SBR_HEADER ||
lastHeader.startFreq != pBsData->startFreq || lastHeader.startFreq != pBsData->startFreq ||
lastHeader.stopFreq != pBsData->stopFreq || lastHeader.stopFreq != pBsData->stopFreq ||
lastHeader.freqScale != pBsData->freqScale || lastHeader.freqScale != pBsData->freqScale ||
@ -904,6 +904,9 @@ static const FRAME_INFO v_frame_info4_8 = { 0, 4, {0, 2, 4, 6, 8}, {1, 1, 1, 1},
break; break;
default: default:
FDK_ASSERT(0); FDK_ASSERT(0);
/* in case assertion checks are disabled, force a definite memory fault at first access */
pTable = NULL;
break;
} }
/* look number of envelopes in table */ /* look number of envelopes in table */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -125,6 +125,7 @@ amm-info@iis.fraunhofer.de
typedef enum typedef enum
{ {
HEADER_NOT_PRESENT, HEADER_NOT_PRESENT,
HEADER_ERROR,
HEADER_OK, HEADER_OK,
HEADER_RESET HEADER_RESET
} }
@ -132,10 +133,10 @@ SBR_HEADER_STATUS;
typedef enum typedef enum
{ {
SBR_NOT_INITIALIZED, SBR_NOT_INITIALIZED = 0,
UPSAMPLING, UPSAMPLING = 1,
SBR_HEADER, SBR_HEADER = 2,
SBR_ACTIVE SBR_ACTIVE = 3
} }
SBR_SYNC_STATE; SBR_SYNC_STATE;
@ -179,6 +180,7 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA;
#define SBRDEC_LOW_POWER 16 /* Flag indicating that Low Power QMF mode shall be used. */ #define SBRDEC_LOW_POWER 16 /* Flag indicating that Low Power QMF mode shall be used. */
#define SBRDEC_PS_DECODED 32 /* Flag indicating that PS was decoded and rendered. */ #define SBRDEC_PS_DECODED 32 /* Flag indicating that PS was decoded and rendered. */
#define SBRDEC_LD_MPS_QMF 512 /* Flag indicating that the LD-MPS QMF shall be used. */ #define SBRDEC_LD_MPS_QMF 512 /* Flag indicating that the LD-MPS QMF shall be used. */
#define SBRDEC_SYNTAX_DRM 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being used. */
#define SBRDEC_DOWNSAMPLE 8192 /* Flag indicating that the downsampling mode is used. */ #define SBRDEC_DOWNSAMPLE 8192 /* Flag indicating that the downsampling mode is used. */
#define SBRDEC_FLUSH 16384 /* Flag is used to flush all elements in use. */ #define SBRDEC_FLUSH 16384 /* Flag is used to flush all elements in use. */
#define SBRDEC_FORCE_RESET 32768 /* Flag is used to force a reset of all elements in use. */ #define SBRDEC_FORCE_RESET 32768 /* Flag is used to force a reset of all elements in use. */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -225,7 +225,14 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
} }
if (resetAnaQmf) { if (resetAnaQmf) {
int qmfErr = qmfInitAnalysisFilterBank ( QMF_FILTER_BANK prvAnaQmf;
int qmfErr;
/* Store current configuration */
FDKmemcpy(&prvAnaQmf, &hSbrDec->AnalysiscQMF, sizeof(QMF_FILTER_BANK));
/* Reset analysis QMF */
qmfErr = qmfInitAnalysisFilterBank (
&hSbrDec->AnalysiscQMF, &hSbrDec->AnalysiscQMF,
hSbrDec->anaQmfStates, hSbrDec->anaQmfStates,
hSbrDec->AnalysiscQMF.no_col, hSbrDec->AnalysiscQMF.no_col,
@ -234,13 +241,22 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
hSbrDec->AnalysiscQMF.no_channels, hSbrDec->AnalysiscQMF.no_channels,
anaQmfFlags | QMF_FLAG_KEEP_STATES anaQmfFlags | QMF_FLAG_KEEP_STATES
); );
if (qmfErr != 0) { if (qmfErr != 0) {
FDK_ASSERT(0); /* Restore old configuration of analysis QMF */
FDKmemcpy(&hSbrDec->AnalysiscQMF, &prvAnaQmf, sizeof(QMF_FILTER_BANK));
} }
} }
if (resetSynQmf) { if (resetSynQmf) {
int qmfErr = qmfInitSynthesisFilterBank ( QMF_FILTER_BANK prvSynQmf;
int qmfErr;
/* Store current configuration */
FDKmemcpy(&prvSynQmf, &hSbrDec->SynthesisQMF, sizeof(QMF_FILTER_BANK));
/* Reset synthesis QMF */
qmfErr = qmfInitSynthesisFilterBank (
&hSbrDec->SynthesisQMF, &hSbrDec->SynthesisQMF,
hSbrDec->pSynQmfStates, hSbrDec->pSynQmfStates,
hSbrDec->SynthesisQMF.no_col, hSbrDec->SynthesisQMF.no_col,
@ -251,7 +267,8 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
); );
if (qmfErr != 0) { if (qmfErr != 0) {
FDK_ASSERT(0); /* Restore old configuration of synthesis QMF */
FDKmemcpy(&hSbrDec->SynthesisQMF, &prvSynQmf, sizeof(QMF_FILTER_BANK));
} }
} }
} }
@ -321,7 +338,8 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */ const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d, HANDLE_PS_DEC h_ps_d,
const UINT flags const UINT flags,
const int codecFrameSize
) )
{ {
int i, slot, reserve; int i, slot, reserve;
@ -348,6 +366,33 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
if (flags & SBRDEC_ELD_GRID) { if (flags & SBRDEC_ELD_GRID) {
/* Choose the right low delay filter bank */ /* Choose the right low delay filter bank */
changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 ); changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 );
/* If the LD-MPS QMF is not available delay the signal by (96-48*ldSbrSamplingRate)
* samples according to ISO/IEC 14496-3:2009/FDAM 2:2010(E) chapter 4.5.2.13. */
if ( (flags & SBRDEC_LD_MPS_QMF)
&& (hSbrDec->AnalysiscQMF.flags & QMF_FLAG_CLDFB) )
{
INT_PCM *pDlyBuf = hSbrDec->coreDelayBuf; /* DLYBUF */
int smpl, delay = 96 >> (!(flags & SBRDEC_DOWNSAMPLE) ? 1 : 0);
/* Create TMPBUF */
C_AALLOC_SCRATCH_START(pcmTemp, INT_PCM, (96));
/* Copy delay samples from INBUF to TMPBUF */
for (smpl = 0; smpl < delay; smpl += 1) {
pcmTemp[smpl] = timeIn[(codecFrameSize-delay+smpl)*strideIn];
}
/* Move input signal remainder to the very end of INBUF */
for (smpl = (codecFrameSize-delay-1)*strideIn; smpl >= 0; smpl -= strideIn) {
timeIn[smpl+delay] = timeIn[smpl];
}
/* Copy delayed samples from last frame from DLYBUF to the very beginning of INBUF */
for (smpl = 0; smpl < delay; smpl += 1) {
timeIn[smpl*strideIn] = pDlyBuf[smpl];
}
/* Copy TMPBUF to DLYBUF */
FDKmemcpy(pDlyBuf, pcmTemp, delay*sizeof(INT_PCM));
/* Destory TMPBUF */
C_AALLOC_SCRATCH_END(pcmTemp, INT_PCM, (96));
}
} }
/* /*
@ -761,7 +806,7 @@ createSbrDec (SBR_CHANNEL * hSbrChannel,
{ {
int qmfErr; int qmfErr;
/* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */ /* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */
const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0; const UINT downSampledFlag = (flags & SBRDEC_DOWNSAMPLE) ? QMF_FLAG_DOWNSAMPLED : 0;
qmfErr = qmfInitAnalysisFilterBank ( qmfErr = qmfInitAnalysisFilterBank (
&hs->AnalysiscQMF, &hs->AnalysiscQMF,
@ -836,6 +881,9 @@ createSbrDec (SBR_CHANNEL * hSbrChannel,
} }
} }
/* Clear input delay line */
FDKmemclear(hs->coreDelayBuf, (96)*sizeof(INT_PCM));
/* assign qmf time slots */ /* assign qmf time slots */
assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP); assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP);

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -118,6 +118,9 @@ typedef struct
FIXP_DBL * WorkBuffer1; FIXP_DBL * WorkBuffer1;
FIXP_DBL * WorkBuffer2; FIXP_DBL * WorkBuffer2;
/* Delayed time input signal needed to align CLDFD with LD-MPS QMF. */
INT_PCM coreDelayBuf[(96)];
/* QMF filter states */ /* QMF filter states */
FIXP_QAS anaQmfStates[(320)]; FIXP_QAS anaQmfStates[(320)];
FIXP_QSS * pSynQmfStates; FIXP_QSS * pSynQmfStates;
@ -182,7 +185,8 @@ sbr_dec (HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */ const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d, HANDLE_PS_DEC h_ps_d,
const UINT flags const UINT flags,
const int codecFrameSize
); );

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -135,6 +135,7 @@ struct SBR_DECODER_INSTANCE
USHORT codecFrameSize; USHORT codecFrameSize;
UCHAR synDownsampleFac; UCHAR synDownsampleFac;
UCHAR numDelayFrames; /* The current number of additional delay frames used for processing. */ UCHAR numDelayFrames; /* The current number of additional delay frames used for processing. */
UCHAR numFlushedFrames; /* The variable counts the number of frames which are flushed consecutively. */
UINT flags; UINT flags;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -189,6 +189,15 @@ const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] =
FL2FXCONST_SGL(3.0f / 4.0f) FL2FXCONST_SGL(3.0f / 4.0f)
}; };
/*! Constants for calculating the number of limiter bands */
const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4] =
{
FL2FXCONST_DBL(1.0f / 4.0f),
FL2FXCONST_DBL(1.2f / 4.0f),
FL2FXCONST_DBL(2.0f / 4.0f),
FL2FXCONST_DBL(3.0f / 4.0f)
};
/*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope */ /*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope */
const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = { const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = {
FL2FXCONST_SGL(0.66666666666666f), FL2FXCONST_SGL(0.66666666666666f),
@ -1176,7 +1185,7 @@ const FIXP_DBL Alphas[NO_ICC_LEVELS] = {
#define FL2FXCONST_PS FL2FXCONST_SGL #define FL2FXCONST_PS FL2FXCONST_SGL
#else #else
#define FIXP_PS FIXP_DBL #define FIXP_PS FIXP_DBL
#define FXP_CAST #define FXP_CAST(x) ((FIXP_DBL)(x))
#define FL2FXCONST_PS FL2FXCONST_DBL #define FL2FXCONST_PS FL2FXCONST_DBL
#endif #endif

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -124,6 +124,7 @@ extern const FIXP_DBL FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRI
extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4];
extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4]; extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4];
extern const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2]; extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2];
extern const FIXP_SGL harmonicPhaseX [2][4]; extern const FIXP_SGL harmonicPhaseX [2][4];

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -128,6 +128,7 @@ amm-info@iis.fraunhofer.de
#include "lpp_tran.h" #include "lpp_tran.h"
#include "transcendent.h" #include "transcendent.h"
#include "FDK_crc.h"
#include "sbrdec_drc.h" #include "sbrdec_drc.h"
@ -137,10 +138,15 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL0 2
#define SBRDECODER_LIB_VL1 2 #define SBRDECODER_LIB_VL1 2
#define SBRDECODER_LIB_VL2 6 #define SBRDECODER_LIB_VL2 12
#define SBRDECODER_LIB_TITLE "SBR Decoder" #define SBRDECODER_LIB_TITLE "SBR Decoder"
#ifdef __ANDROID__
#define SBRDECODER_LIB_BUILD_DATE ""
#define SBRDECODER_LIB_BUILD_TIME ""
#else
#define SBRDECODER_LIB_BUILD_DATE __DATE__ #define SBRDECODER_LIB_BUILD_DATE __DATE__
#define SBRDECODER_LIB_BUILD_TIME __TIME__ #define SBRDECODER_LIB_BUILD_TIME __TIME__
#endif
@ -189,6 +195,33 @@ static void copySbrHeader( HANDLE_SBR_HEADER_DATA hDst, const HANDLE_SBR_HEADER_
hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi; hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi;
} }
static int compareSbrHeader( const HANDLE_SBR_HEADER_DATA hHdr1, const HANDLE_SBR_HEADER_DATA hHdr2 )
{
int result = 0;
/* compare basic data */
result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0;
result |= (hHdr1->status != hHdr2->status) ? 1 : 0;
result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0;
result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0;
result |= (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0;
result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0;
result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0;
/* compare bitstream data */
result |= FDKmemcmp( &hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS) );
result |= FDKmemcmp( &hHdr1->bs_info, &hHdr2->bs_info, sizeof(SBR_HEADER_DATA_BS_INFO) );
/* compare frequency band data */
result |= FDKmemcmp( &hHdr1->freqBandData, &hHdr2->freqBandData, (8+MAX_NUM_LIMITERS+1)*sizeof(UCHAR) );
result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableLo, hHdr2->freqBandData.freqBandTableLo, (MAX_FREQ_COEFFS/2+1)*sizeof(UCHAR) );
result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableHi, hHdr2->freqBandData.freqBandTableHi, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) );
result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableNoise, hHdr2->freqBandData.freqBandTableNoise, (MAX_NOISE_COEFFS+1)*sizeof(UCHAR) );
result |= FDKmemcmp( hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) );
return result;
}
/*! /*!
\brief Reset SBR decoder. \brief Reset SBR decoder.
@ -313,7 +346,6 @@ SBR_ERROR sbrDecoder_ResetElement (
case AOT_PS: case AOT_PS:
case AOT_ER_AAC_SCAL: case AOT_ER_AAC_SCAL:
case AOT_DRM_AAC: case AOT_DRM_AAC:
case AOT_DRM_SURROUND:
if (CreatePsDec ( &self->hParametricStereoDec, samplesPerFrame )) { if (CreatePsDec ( &self->hParametricStereoDec, samplesPerFrame )) {
sbrError = SBRDEC_CREATE_ERROR; sbrError = SBRDEC_CREATE_ERROR;
goto bail; goto bail;
@ -387,6 +419,7 @@ int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec)
case AOT_PS: case AOT_PS:
case AOT_ER_AAC_SCAL: case AOT_ER_AAC_SCAL:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
case AOT_DRM_AAC:
return 1; return 1;
default: default:
return 0; return 0;
@ -459,6 +492,8 @@ SBR_ERROR sbrDecoder_InitElement (
self->flags = 0; self->flags = 0;
self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0; self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0;
self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0;
self->flags |= (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL|SBRDEC_SYNTAX_DRM : 0;
/* Init SBR elements */ /* Init SBR elements */
{ {
@ -498,7 +533,6 @@ SBR_ERROR sbrDecoder_InitElement (
case AOT_PS: case AOT_PS:
case AOT_ER_AAC_SCAL: case AOT_ER_AAC_SCAL:
case AOT_DRM_AAC: case AOT_DRM_AAC:
case AOT_DRM_SURROUND:
elChannels = 2; elChannels = 2;
break; break;
default: default:
@ -925,24 +959,73 @@ SBR_ERROR sbrDecoder_Parse(
) )
{ {
SBR_DECODER_ELEMENT *hSbrElement; SBR_DECODER_ELEMENT *hSbrElement;
HANDLE_SBR_HEADER_DATA hSbrHeader; HANDLE_SBR_HEADER_DATA hSbrHeader = NULL;
HANDLE_SBR_CHANNEL *pSbrChannel; HANDLE_SBR_CHANNEL *pSbrChannel;
SBR_FRAME_DATA *hFrameDataLeft; SBR_FRAME_DATA *hFrameDataLeft;
SBR_FRAME_DATA *hFrameDataRight; SBR_FRAME_DATA *hFrameDataRight;
SBR_ERROR errorStatus = SBRDEC_OK; SBR_ERROR errorStatus = SBRDEC_OK;
SBR_SYNC_STATE initialSyncState;
SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
INT startPos; INT startPos;
INT CRCLen = 0; INT CRCLen = 0;
HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
FDK_CRCINFO crcInfo; /* shall be used for all other CRCs in the future (TBD) */
INT crcReg = 0;
USHORT drmSbrCrc = 0;
int stereo; int stereo;
int fDoDecodeSbrData = 1; int fDoDecodeSbrData = 1;
int lastSlot, lastHdrSlot = 0, thisHdrSlot; int lastSlot, lastHdrSlot = 0, thisHdrSlot;
/* Reverse bits of DRM SBR payload */
if ( (self->flags & SBRDEC_SYNTAX_DRM) && *count > 0 )
{
UCHAR *bsBufferDrm = (UCHAR*)self->workBuffer1;
HANDLE_FDK_BITSTREAM hBsBwd = (HANDLE_FDK_BITSTREAM) (bsBufferDrm + (512));
int dataBytes, dataBits;
dataBits = *count;
if (dataBits > ((512)*8)) {
/* do not flip more data than needed */
dataBits = (512)*8;
}
dataBytes = (dataBits+7)>>3;
int j;
if ((j = (int)FDKgetValidBits(hBs)) != 8) {
FDKpushBiDirectional(hBs, (j-8));
}
j = 0;
for ( ; dataBytes > 0; dataBytes--)
{
int i;
UCHAR tmpByte;
UCHAR buffer = 0x00;
tmpByte = (UCHAR) FDKreadBits(hBs, 8);
for (i = 0; i < 4; i++) {
int shift = 2 * i + 1;
buffer |= (tmpByte & (0x08>>i)) << shift;
buffer |= (tmpByte & (0x10<<i)) >> shift;
}
bsBufferDrm[j++] = buffer;
FDKpushBack(hBs, 16);
}
FDKinitBitStream(hBsBwd, bsBufferDrm, (512), dataBits, BS_READER);
/* Use reversed data */
hBs = hBsBwd;
bsPayLen = *count;
}
/* Remember start position of SBR element */ /* Remember start position of SBR element */
startPos = FDKgetValidBits(hBs); startPos = FDKgetValidBits(hBs);
@ -967,7 +1050,6 @@ SBR_ERROR sbrDecoder_Parse(
hFrameDataLeft = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; hFrameDataLeft = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
initialSyncState = hSbrHeader->syncState;
/* reset PS flag; will be set after PS was found */ /* reset PS flag; will be set after PS was found */
self->flags &= ~SBRDEC_PS_DECODED; self->flags &= ~SBRDEC_PS_DECODED;
@ -1003,12 +1085,19 @@ SBR_ERROR sbrDecoder_Parse(
*/ */
if (fDoDecodeSbrData) if (fDoDecodeSbrData)
{ {
if (crcFlag == 1) { if (crcFlag) {
switch (self->coreCodec) { switch (self->coreCodec) {
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
FDKpushFor (hBs, 10); FDKpushFor (hBs, 10);
/* check sbrcrc later: we don't know the payload length now */ /* check sbrcrc later: we don't know the payload length now */
break; break;
case AOT_DRM_AAC:
drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
/* Setup CRC decoder */
FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
/* Start CRC region */
crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
break;
default: default:
CRCLen = bsPayLen - 10; /* change: 0 => i */ CRCLen = bsPayLen - 10; /* change: 0 => i */
if (CRCLen < 0) { if (CRCLen < 0) {
@ -1053,6 +1142,7 @@ SBR_ERROR sbrDecoder_Parse(
hSbrHeader->syncState = SBR_HEADER; hSbrHeader->syncState = SBR_HEADER;
} else { } else {
hSbrHeader->syncState = SBR_NOT_INITIALIZED; hSbrHeader->syncState = SBR_NOT_INITIALIZED;
headerStatus = HEADER_ERROR;
} }
} }
@ -1102,7 +1192,7 @@ SBR_ERROR sbrDecoder_Parse(
valBits = (INT)FDKgetValidBits(hBs); valBits = (INT)FDKgetValidBits(hBs);
} }
if ( crcFlag == 1 ) { if ( crcFlag ) {
switch (self->coreCodec) { switch (self->coreCodec) {
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
{ {
@ -1114,6 +1204,14 @@ SBR_ERROR sbrDecoder_Parse(
FDKpushFor(hBs, crcLen); FDKpushFor(hBs, crcLen);
} }
break; break;
case AOT_DRM_AAC:
/* End CRC region */
FDKcrcEndReg(&crcInfo, hBs, crcReg);
/* Check CRC */
if ((FDKcrcGetCRC(&crcInfo)^0xFF) != drmSbrCrc) {
fDoDecodeSbrData = 0;
}
break;
default: default:
break; break;
} }
@ -1164,8 +1262,25 @@ SBR_ERROR sbrDecoder_Parse(
} }
bail: bail:
if (errorStatus == SBRDEC_OK) {
if (headerStatus == HEADER_NOT_PRESENT) { if ( self->flags & SBRDEC_SYNTAX_DRM )
{
hBs = hBsOriginal;
}
if ( (errorStatus == SBRDEC_OK)
|| ( (errorStatus == SBRDEC_PARSE_ERROR)
&& (headerStatus != HEADER_ERROR) ) )
{
int useOldHdr = ( (headerStatus == HEADER_NOT_PRESENT)
|| (headerStatus == HEADER_ERROR) ) ? 1 : 0;
if (!useOldHdr && (thisHdrSlot != lastHdrSlot)) {
useOldHdr |= ( compareSbrHeader( hSbrHeader,
&self->sbrHeader[elementIndex][lastHdrSlot] ) == 0 ) ? 1 : 0;
}
if (useOldHdr != 0) {
/* Use the old header for this frame */ /* Use the old header for this frame */
hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot; hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot;
} else { } else {
@ -1226,12 +1341,21 @@ sbrDecoder_DecodeElement (
int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */ int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */
if (self->flags & SBRDEC_FLUSH) { if (self->flags & SBRDEC_FLUSH) {
/* Move frame pointer to the next slot which is up to be decoded/applied next */ if ( self->numFlushedFrames > self->numDelayFrames ) {
hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1); int hdrIdx;
/* Update header and frame data pointer because they have already been set */ /* No valid SBR payload available, hence switch to upsampling (in all headers) */
hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]]; for (hdrIdx = 0; hdrIdx < ((1)+1); hdrIdx += 1) {
hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; }
}
else {
/* Move frame pointer to the next slot which is up to be decoded/applied next */
hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1);
/* Update header and frame data pointer because they have already been set */
hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
}
} }
/* Update the header error flag */ /* Update the header error flag */
@ -1351,7 +1475,8 @@ sbrDecoder_DecodeElement (
&pSbrChannel[0]->prevFrameData, &pSbrChannel[0]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE), (hSbrHeader->syncState == SBR_ACTIVE),
h_ps_d, h_ps_d,
self->flags self->flags,
codecFrameSize
); );
if (stereo) { if (stereo) {
@ -1368,7 +1493,8 @@ sbrDecoder_DecodeElement (
&pSbrChannel[1]->prevFrameData, &pSbrChannel[1]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE), (hSbrHeader->syncState == SBR_ACTIVE),
NULL, NULL,
self->flags self->flags,
codecFrameSize
); );
} }
@ -1384,20 +1510,21 @@ sbrDecoder_DecodeElement (
if ( !(self->flags & SBRDEC_PS_DECODED) ) { if ( !(self->flags & SBRDEC_PS_DECODED) ) {
/* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */ /* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */
/* So copy left channel to right channel. */ /* So copy left channel to right channel. */
int copyFrameSize = codecFrameSize * 2 / self->synDownsampleFac;
if (interleaved) { if (interleaved) {
INT_PCM *ptr; INT_PCM *ptr;
INT i; INT i;
FDK_ASSERT(strideOut == 2); FDK_ASSERT(strideOut == 2);
ptr = timeData; ptr = timeData;
for (i = codecFrameSize; i--; ) for (i = copyFrameSize>>1; i--; )
{ {
INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */ INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */
tmp = *ptr++; *ptr++ = tmp; tmp = *ptr++; *ptr++ = tmp;
tmp = *ptr++; *ptr++ = tmp; tmp = *ptr++; *ptr++ = tmp;
} }
} else { } else {
FDKmemcpy( timeData+2*codecFrameSize, timeData, 2*codecFrameSize*sizeof(INT_PCM) ); FDKmemcpy( timeData+copyFrameSize, timeData, copyFrameSize*sizeof(INT_PCM) );
} }
} }
*numOutChannels = 2; /* Output minimum two channels when PS is enabled. */ *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */
@ -1461,14 +1588,23 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
self->flags &= ~SBRDEC_PS_DECODED; self->flags &= ~SBRDEC_PS_DECODED;
} }
if ( self->flags & SBRDEC_FLUSH ) {
/* flushing is signalized, hence increment the flush frame counter */
self->numFlushedFrames++;
}
else {
/* no flushing is signalized, hence reset the flush frame counter */
self->numFlushedFrames = 0;
}
/* Loop over SBR elements */ /* Loop over SBR elements */
for (sbrElementNum = 0; sbrElementNum<self->numSbrElements; sbrElementNum++) for (sbrElementNum = 0; sbrElementNum<self->numSbrElements; sbrElementNum++)
{ {
int numElementChan; int numElementChan;
if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) { if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) {
errorStatus = SBRDEC_UNSUPPORTED_CONFIG; /* Disable PS and try decoding SBR mono. */
goto bail; psPossible = 0;
} }
numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1; numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1;
@ -1576,6 +1712,7 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info )
| CAPF_SBR_HQ | CAPF_SBR_HQ
| CAPF_SBR_LP | CAPF_SBR_LP
| CAPF_SBR_PS_MPEG | CAPF_SBR_PS_MPEG
| CAPF_SBR_DRM_BS
| CAPF_SBR_CONCEALMENT | CAPF_SBR_CONCEALMENT
| CAPF_SBR_DRC | CAPF_SBR_DRC
; ;
@ -1604,6 +1741,9 @@ UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self )
/* Low delay SBR: */ /* Low delay SBR: */
{ {
outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */ outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
if (flags & SBRDEC_LD_MPS_QMF) {
outputDelay += 32;
}
} }
} }
else if (!IS_USAC(self->coreCodec)) { else if (!IS_USAC(self->coreCodec)) {

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -135,6 +135,12 @@ enum
SBR_SYNTAX_DRM_CRC = 0x0008 SBR_SYNTAX_DRM_CRC = 0x0008
}; };
typedef enum
{
FREQ_RES_LOW = 0,
FREQ_RES_HIGH
} FREQ_RES;
typedef struct typedef struct
{ {
CODEC_TYPE coreCoder; /*!< LC or ELD */ CODEC_TYPE coreCoder; /*!< LC or ELD */
@ -168,8 +174,9 @@ typedef struct sbrConfiguration
INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */ INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */
INT parametricCoding; /*!< Flag: usage of parametric coding tool. */ INT parametricCoding; /*!< Flag: usage of parametric coding tool. */
INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core encoder. */ INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core encoder. */
int freq_res_fixfix[3]; /*!< Frequency resolution of envelopes in frame class FIXFIX FREQ_RES freq_res_fixfix[2];/*!< Frequency resolution of envelopes in frame class FIXFIX, for non-split case and split case */
0=1 Env; 1=2 Env; 2=4 Env; */ UCHAR fResTransIsLow; /*!< Frequency resolution of envelopes in transient frames: low (0) or variable (1) */
/* /*
core coder dependent tuning parameters core coder dependent tuning parameters
*/ */
@ -221,6 +228,8 @@ typedef struct sbrConfiguration
INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */ INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */
INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */ INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */
UCHAR init_amp_res_FF; UCHAR init_amp_res_FF;
FIXP_DBL threshold_AmpRes_FF_m;
SCHAR threshold_AmpRes_FF_e;
} sbrConfiguration, *sbrConfigurationPtr ; } sbrConfiguration, *sbrConfigurationPtr ;
typedef struct SBR_CONFIG_DATA typedef struct SBR_CONFIG_DATA
@ -237,7 +246,7 @@ typedef struct SBR_CONFIG_DATA
INT noQmfBands; /**< Number of QMF frequency bands. */ INT noQmfBands; /**< Number of QMF frequency bands. */
INT noQmfSlots; /**< Number of QMF slots. */ INT noQmfSlots; /**< Number of QMF slots. */
UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeefs actually needed for lowres. */ UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeffs actually needed for lowres. */
UCHAR *v_k_master; /**< Master BandTable where freqBandTable is derived from. */ UCHAR *v_k_master; /**< Master BandTable where freqBandTable is derived from. */
@ -249,6 +258,8 @@ typedef struct SBR_CONFIG_DATA
INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */ INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */
INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */ INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */
UCHAR initAmpResFF; UCHAR initAmpResFF;
FIXP_DBL thresholdAmpResFF_m;
SCHAR thresholdAmpResFF_e;
} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA; } SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA;
typedef struct { typedef struct {

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -283,9 +283,7 @@ void sbrEncoder_GetHeader(SBR_ENCODER *sbrEncoder,
INT element_index, INT element_index,
int fSendHeaders) int fSendHeaders)
{ {
int bits; encodeSbrHeaderData (&sbrEncoder->sbrElement[element_index]->sbrHeaderData, hBs);
bits = encodeSbrHeaderData (&sbrEncoder->sbrElement[element_index]->sbrHeaderData, hBs);
if (fSendHeaders == 0) { if (fSendHeaders == 0) {
/* Prevent header being embedded into the SBR payload. */ /* Prevent header being embedded into the SBR payload. */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -141,8 +141,8 @@ struct SBR_ENV_DATA
{ {
INT sbr_xpos_ctrl; INT sbr_xpos_ctrl;
INT freq_res_fixfix; FREQ_RES freq_res_fixfix[2];
UCHAR fResTransIsLow;
INVF_MODE sbr_invf_mode; INVF_MODE sbr_invf_mode;
INVF_MODE sbr_invf_mode_vec[MAX_NUM_NOISE_VALUES]; INVF_MODE sbr_invf_mode_vec[MAX_NUM_NOISE_VALUES];
@ -205,6 +205,8 @@ struct SBR_ENV_DATA
INT balance; INT balance;
AMP_RES init_sbr_amp_res; AMP_RES init_sbr_amp_res;
AMP_RES currentAmpResFF; AMP_RES currentAmpResFF;
FIXP_DBL ton_HF[SBR_GLOBAL_TONALITY_VALUES]; /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
FIXP_DBL global_tonality;
/* extended data */ /* extended data */
INT extended_data; INT extended_data;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -103,6 +103,114 @@ static const UCHAR panTable[2][10] = { { 0, 2, 4, 6, 8,12,16,20,24},
static const UCHAR maxIndex[2] = {9, 5}; static const UCHAR maxIndex[2] = {9, 5};
/******************************************************************************
Functionname: FDKsbrEnc_GetTonality
******************************************************************************/
/***************************************************************************/
/*!
\brief Calculates complete energy per band from the energy values
of the QMF subsamples.
\brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas()
\brief noEstPerFrame - number of estimations per frame
\brief startIndex - start index for the quota matrix
\brief Energies - energy matrix
\brief startBand - start band
\brief stopBand - number of QMF bands
\brief numberCols - number of QMF subsamples
\return mean tonality of the 5 bands with the highest energy
scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT
****************************************************************************/
static FIXP_DBL FDKsbrEnc_GetTonality(
const FIXP_DBL *const *quotaMatrix,
const INT noEstPerFrame,
const INT startIndex,
const FIXP_DBL *const *Energies,
const UCHAR startBand,
const INT stopBand,
const INT numberCols
)
{
UCHAR b, e, k;
INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = { -1, -1, -1, -1, -1 };
FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
FIXP_DBL energyBand[QMF_CHANNELS];
INT maxNEnergyValues; /* max. number of max. energy values */
/*** Sum up energies for each band ***/
FDK_ASSERT(numberCols==15||numberCols==16);
/* numberCols is always 15 or 16 for ELD. In case of 16 bands, the
energyBands are initialized with the [15]th column.
The rest of the column energies are added in the next step. */
if (numberCols==15) {
for (b=startBand; b<stopBand; b++) {
energyBand[b]=FL2FXCONST_DBL(0.0f);
}
} else {
for (b=startBand; b<stopBand; b++) {
energyBand[b]=Energies[15][b]>>4;
}
}
for (k=0; k<15; k++) {
for (b=startBand; b<stopBand; b++) {
energyBand[b] += Energies[k][b]>>4;
}
}
/*** Determine 5 highest band-energies ***/
maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand-startBand);
/* Get min. value in energyMax array */
energyMaxMin = energyMax[0] = energyBand[startBand];
no_enMaxBand[0] = startBand;
posEnergyMaxMin = 0;
for (k=1; k<maxNEnergyValues; k++) {
energyMax[k] = energyBand[startBand+k];
no_enMaxBand[k] = startBand+k;
if (energyMaxMin > energyMax[k]) {
energyMaxMin = energyMax[k];
posEnergyMaxMin = k;
}
}
for (b=startBand+maxNEnergyValues; b<stopBand; b++) {
if (energyBand[b] > energyMaxMin) {
energyMax[posEnergyMaxMin] = energyBand[b];
no_enMaxBand[posEnergyMaxMin] = b;
/* Again, get min. value in energyMax array */
energyMaxMin = energyMax[0];
posEnergyMaxMin = 0;
for (k=1; k<maxNEnergyValues; k++) {
if (energyMaxMin > energyMax[k]) {
energyMaxMin = energyMax[k];
posEnergyMaxMin = k;
}
}
}
}
/*** End determine 5 highest band-energies ***/
/* Get tonality values for 5 highest energies */
for (e=0; e<maxNEnergyValues; e++) {
tonalityBand[e]=FL2FXCONST_DBL(0.0f);
for (k=0; k<noEstPerFrame; k++) {
tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
}
globalTonality += tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
}
return globalTonality;
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -919,10 +1027,42 @@ FDKsbrEnc_extractSbrEnvelope1 (
hEnvChan->qmfScale); hEnvChan->qmfScale);
if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
FIXP_DBL tonality = FDKsbrEnc_GetTonality (
hEnvChan->TonCorr.quotaMatrix,
hEnvChan->TonCorr.numberOfEstimatesPerFrame,
hEnvChan->TonCorr.startIndexMatrix,
sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
h_con->freqBandTable[HI][0]+1,
h_con->noQmfBands,
sbrExtrEnv->no_cols
);
hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
hEnvChan->encEnvData.ton_HF[0] = tonality;
/* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
hEnvChan->encEnvData.global_tonality = (hEnvChan->encEnvData.ton_HF[0]>>1) + (hEnvChan->encEnvData.ton_HF[1]>>1);
}
/* /*
Transient detection COEFF Transform OK Transient detection COEFF Transform OK
*/ */
if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
{
FDKsbrEnc_fastTransientDetect(
&hEnvChan->sbrFastTransientDetector,
sbrExtrEnv->YBuffer,
sbrExtrEnv->YBufferScale,
sbrExtrEnv->YBufferWriteOffset,
eData->transient_info
);
}
else
{
FDKsbrEnc_transientDetect(&hEnvChan->sbrTransientDetector, FDKsbrEnc_transientDetect(&hEnvChan->sbrTransientDetector,
sbrExtrEnv->YBuffer, sbrExtrEnv->YBuffer,
sbrExtrEnv->YBufferScale, sbrExtrEnv->YBufferScale,
@ -931,6 +1071,7 @@ FDKsbrEnc_extractSbrEnvelope1 (
sbrExtrEnv->YBufferSzShift, sbrExtrEnv->YBufferSzShift,
sbrExtrEnv->time_step, sbrExtrEnv->time_step,
hEnvChan->SbrEnvFrame.frameMiddleSlot); hEnvChan->SbrEnvFrame.frameMiddleSlot);
}
@ -951,7 +1092,8 @@ FDKsbrEnc_extractSbrEnvelope1 (
sbrExtrEnv->YBufferSzShift, sbrExtrEnv->YBufferSzShift,
h_con->nSfb[1], h_con->nSfb[1],
sbrExtrEnv->time_step, sbrExtrEnv->time_step,
sbrExtrEnv->no_cols); sbrExtrEnv->no_cols,
&hEnvChan->encEnvData.global_tonality);
} }
@ -1128,12 +1270,26 @@ FDKsbrEnc_extractSbrEnvelope2 (
&& ( ed->nEnvelopes == 1 ) ) && ( ed->nEnvelopes == 1 ) )
{ {
if (hEnvChan->encEnvData.ldGrid) if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF; {
else /* Note: global_tonaliy_float_value == ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
threshold_float_value == ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); */
/* decision of SBR_AMP_RES */
if (fIsLessThan( /* global_tonality > threshold ? */
h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
hEnvChan->encEnvData.global_tonality, RELAXATION_SHIFT+2 )
)
{
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
}
else {
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
}
} else {
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
}
if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) { if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData, FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData,
&hEnvChan->sbrCodeEnvelope, &hEnvChan->sbrCodeEnvelope,
@ -1172,7 +1328,12 @@ FDKsbrEnc_extractSbrEnvelope2 (
} }
/* Low energy in low band fix */ /* Low energy in low band fix */
if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)) if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy
&& hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
/* The fix needs the non-fast transient detector running.
It sets prevLowBandEnergy and prevHighBandEnergy. */
&& !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
)
{ {
int i; int i;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -127,6 +127,7 @@ typedef SBR_EXTRACT_ENVELOPE *HANDLE_SBR_EXTRACT_ENVELOPE;
struct ENV_CHANNEL struct ENV_CHANNEL
{ {
FAST_TRAN_DETECTOR sbrFastTransientDetector;
SBR_TRANSIENT_DETECTOR sbrTransientDetector; SBR_TRANSIENT_DETECTOR sbrTransientDetector;
SBR_CODE_ENVELOPE sbrCodeEnvelope; SBR_CODE_ENVELOPE sbrCodeEnvelope;
SBR_CODE_ENVELOPE sbrCodeNoiseFloor; SBR_CODE_ENVELOPE sbrCodeNoiseFloor;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -266,7 +266,7 @@ static void calcCtrlSignal (HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
static void ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid, static void ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
HANDLE_SBR_FRAME_INFO hFrameInfo, HANDLE_SBR_FRAME_INFO hFrameInfo,
INT freq_res_fixfix); FREQ_RES *freq_res_fixfix);
/* table for 8 time slot index */ /* table for 8 time slot index */
@ -341,8 +341,9 @@ static const FREQ_RES freqRes_table_16[16] = {
static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo, static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
HANDLE_SBR_GRID hSbrGrid, HANDLE_SBR_GRID hSbrGrid,
int tranPosInternal, int tranPosInternal,
int numberTimeSlots int numberTimeSlots,
); UCHAR fResTransIsLow
);
/*! /*!
@ -402,11 +403,10 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
const int *v_tuningFreq = v_tuning + 3; const int *v_tuningFreq = v_tuning + 3;
hSbrEnvFrame->v_tuningSegm = v_tuningSegm; hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
INT freq_res_fixfix = hSbrEnvFrame->freq_res_fixfix;
if (ldGrid) { if (ldGrid) {
/* in case there was a transient at the very end of the previous frame, start with a transient envelope */ /* in case there was a transient at the very end of the previous frame, start with a transient envelope */
if(v_transient_info_pre[1] && (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)){ if ( !tranFlag && v_transient_info_pre[1] && (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance) ){
tranFlag = 1; tranFlag = 1;
tranPos = 0; tranPos = 0;
} }
@ -529,7 +529,8 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
generateFixFixOnly ( &(hSbrEnvFrame->SbrFrameInfo), generateFixFixOnly ( &(hSbrEnvFrame->SbrFrameInfo),
&(hSbrEnvFrame->SbrGrid), &(hSbrEnvFrame->SbrGrid),
tranPosInternal, tranPosInternal,
numberTimeSlots numberTimeSlots,
hSbrEnvFrame->fResTransIsLow
); );
return &(hSbrEnvFrame->SbrFrameInfo); return &(hSbrEnvFrame->SbrFrameInfo);
@ -677,7 +678,7 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
ctrlSignal2FrameInfo (&hSbrEnvFrame->SbrGrid, ctrlSignal2FrameInfo (&hSbrEnvFrame->SbrGrid,
&hSbrEnvFrame->SbrFrameInfo, &hSbrEnvFrame->SbrFrameInfo,
freq_res_fixfix); hSbrEnvFrame->freq_res_fixfix);
return &hSbrEnvFrame->SbrFrameInfo; return &hSbrEnvFrame->SbrFrameInfo;
} }
@ -692,7 +693,8 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo, static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
HANDLE_SBR_GRID hSbrGrid, HANDLE_SBR_GRID hSbrGrid,
int tranPosInternal, int tranPosInternal,
int numberTimeSlots int numberTimeSlots,
UCHAR fResTransIsLow
) )
{ {
int nEnv, i, k=0, tranIdx; int nEnv, i, k=0, tranIdx;
@ -727,8 +729,12 @@ static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
/* adjust segment-frequency-resolution according to the segment-length */ /* adjust segment-frequency-resolution according to the segment-length */
for (i=0; i<nEnv; i++){ for (i=0; i<nEnv; i++){
k = hSbrFrameInfo->borders[i+1] - hSbrFrameInfo->borders[i]; k = hSbrFrameInfo->borders[i+1] - hSbrFrameInfo->borders[i];
hSbrFrameInfo->freqRes[i] = freqResTable[k]; if (!fResTransIsLow)
hSbrGrid->v_f[i] = freqResTable[k]; hSbrFrameInfo->freqRes[i] = freqResTable[k];
else
hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i];
} }
hSbrFrameInfo->nEnvelopes = nEnv; hSbrFrameInfo->nEnvelopes = nEnv;
@ -765,15 +771,16 @@ static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
*******************************************************************************/ *******************************************************************************/
void void
FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, FDKsbrEnc_initFrameInfoGenerator (
INT allowSpread, HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
INT numEnvStatic, INT allowSpread,
INT staticFraming, INT numEnvStatic,
INT timeSlots, INT staticFraming,
INT freq_res_fixfix INT timeSlots,
,int ldGrid const FREQ_RES* freq_res_fixfix
) ,UCHAR fResTransIsLow,
INT ldGrid
)
{ /* FH 00-06-26 */ { /* FH 00-06-26 */
FDKmemclear(hSbrEnvFrame,sizeof(SBR_ENVELOPE_FRAME )); FDKmemclear(hSbrEnvFrame,sizeof(SBR_ENVELOPE_FRAME ));
@ -786,7 +793,9 @@ FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
hSbrEnvFrame->allowSpread = allowSpread; hSbrEnvFrame->allowSpread = allowSpread;
hSbrEnvFrame->numEnvStatic = numEnvStatic; hSbrEnvFrame->numEnvStatic = numEnvStatic;
hSbrEnvFrame->staticFraming = staticFraming; hSbrEnvFrame->staticFraming = staticFraming;
hSbrEnvFrame->freq_res_fixfix = freq_res_fixfix; hSbrEnvFrame->freq_res_fixfix[0] = freq_res_fixfix[0];
hSbrEnvFrame->freq_res_fixfix[1] = freq_res_fixfix[1];
hSbrEnvFrame->fResTransIsLow = fResTransIsLow;
hSbrEnvFrame->length_v_bord = 0; hSbrEnvFrame->length_v_bord = 0;
hSbrEnvFrame->length_v_bordFollow = 0; hSbrEnvFrame->length_v_bordFollow = 0;
@ -804,6 +813,7 @@ FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
hSbrEnvFrame->dmin = 2; hSbrEnvFrame->dmin = 2;
hSbrEnvFrame->dmax = 16; hSbrEnvFrame->dmax = 16;
hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD; hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
} else } else
switch(timeSlots){ switch(timeSlots){
case NUMBER_TIME_SLOTS_1920: case NUMBER_TIME_SLOTS_1920:
@ -1862,19 +1872,28 @@ createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv, INT nTimeSlots
Functionname: ctrlSignal2FrameInfo Functionname: ctrlSignal2FrameInfo
******************************************************************************* *******************************************************************************
Description: Calculates frame_info struct from control signal. Description: Convert "clear-text" sbr_grid() to "frame info" used by the
envelope and noise floor estimators.
This is basically (except for "low level" calculations) the
bitstream decoder defined in the MPEG-4 standard, sub clause
4.6.18.3.3, Time / Frequency Grid. See inline comments for
explanation of the shorten and noise border algorithms.
Arguments: hSbrGrid - source Arguments: hSbrGrid - source
hSbrFrameInfo - destination hSbrFrameInfo - destination
freq_res_fixfix - frequency resolution for FIXFIX frames
Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct
*******************************************************************************/ *******************************************************************************/
static void static void
ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid, ctrlSignal2FrameInfo (
HANDLE_SBR_FRAME_INFO hSbrFrameInfo, HANDLE_SBR_GRID hSbrGrid, /* input : the grid handle */
INT freq_res_fixfix) HANDLE_SBR_FRAME_INFO hSbrFrameInfo, /* output: the frame info handle */
FREQ_RES *freq_res_fixfix /* in/out: frequency resolution for FIXFIX frames */
)
{ {
INT frameSplit = 0;
INT nEnv = 0, border = 0, i, k, p /*?*/; INT nEnv = 0, border = 0, i, k, p /*?*/;
INT *v_r = hSbrGrid->bs_rel_bord; INT *v_r = hSbrGrid->bs_rel_bord;
INT *v_f = hSbrGrid->v_f; INT *v_f = hSbrGrid->v_f;
@ -1887,17 +1906,10 @@ ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
case FIXFIX: case FIXFIX:
createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots); createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
/* At this point all frequency resolutions are set to FREQ_RES_HIGH, so frameSplit = (hSbrFrameInfo->nEnvelopes > 1);
* only if freq_res_fixfix is set to FREQ_RES_LOW, they all have to be for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
* changed. hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] = freq_res_fixfix[frameSplit];
* snd */
if (freq_res_fixfix == FREQ_RES_LOW) {
for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
}
} }
/* ELD: store current frequency resolution */
hSbrGrid->v_f[0] = hSbrFrameInfo->freqRes[0];
break; break;
case FIXVAR: case FIXVAR:

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -89,6 +89,7 @@ amm-info@iis.fraunhofer.de
#define _FRAM_GEN_H #define _FRAM_GEN_H
#include "sbr_def.h" /* for MAX_ENVELOPES and MAX_NOISE_ENVELOPES in struct FRAME_INFO and CODEC_TYPE */ #include "sbr_def.h" /* for MAX_ENVELOPES and MAX_NOISE_ENVELOPES in struct FRAME_INFO and CODEC_TYPE */
#include "sbr_encoder.h" /* for FREQ_RES */
#define MAX_ENVELOPES_VARVAR MAX_ENVELOPES /*!< worst case number of envelopes in a VARVAR frame */ #define MAX_ENVELOPES_VARVAR MAX_ENVELOPES /*!< worst case number of envelopes in a VARVAR frame */
#define MAX_ENVELOPES_FIXVAR_VARFIX 4 /*!< worst case number of envelopes in VARFIX and FIXVAR frames */ #define MAX_ENVELOPES_FIXVAR_VARFIX 4 /*!< worst case number of envelopes in VARFIX and FIXVAR frames */
@ -114,7 +115,7 @@ typedef enum {
#define NUMBER_TIME_SLOTS_1920 15 #define NUMBER_TIME_SLOTS_1920 15
#define LD_PRETRAN_OFF 3 #define LD_PRETRAN_OFF 3
#define FRAME_MIDDLE_SLOT_512LD 0 #define FRAME_MIDDLE_SLOT_512LD 4
#define NUMBER_TIME_SLOTS_512LD 8 #define NUMBER_TIME_SLOTS_512LD 8
#define TRANSIENT_OFFSET_LD 0 #define TRANSIENT_OFFSET_LD 0
@ -248,9 +249,10 @@ typedef struct
INT frameMiddleSlot; /*!< transient detector offset in SBR timeslots */ INT frameMiddleSlot; /*!< transient detector offset in SBR timeslots */
/* basic tuning parameters */ /* basic tuning parameters */
INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of bs_frame_class = FIXFIX */ INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of bs_frame_class = FIXFIX */
INT numEnvStatic; /*!< number of envelopes per frame for static framing */ INT numEnvStatic; /*!< number of envelopes per frame for static framing */
INT freq_res_fixfix; /*!< envelope frequency resolution to use for bs_frame_class = FIXFIX */ FREQ_RES freq_res_fixfix[2]; /*!< envelope frequency resolution to use for bs_frame_class = FIXFIX; single env and split */
UCHAR fResTransIsLow; /*!< frequency resolution for transient frames - always low (0) or according to table (1) */
/* expert tuning parameters */ /* expert tuning parameters */
const int *v_tuningSegm; /*!< segment lengths to use around transient */ const int *v_tuningSegm; /*!< segment lengths to use around transient */
@ -286,14 +288,16 @@ typedef SBR_ENVELOPE_FRAME *HANDLE_SBR_ENVELOPE_FRAME;
void void
FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, FDKsbrEnc_initFrameInfoGenerator (
INT allowSpread, HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
INT numEnvStatic, INT allowSpread,
INT staticFraming, INT numEnvStatic,
INT timeSlots, INT staticFraming,
INT freq_res_fixfix INT timeSlots,
,int ldGrid const FREQ_RES* freq_res_fixfix
); ,UCHAR fResTransIsLow,
INT ldGrid
);
HANDLE_SBR_FRAME_INFO HANDLE_SBR_FRAME_INFO
FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -663,10 +663,27 @@ static void transientCleanUp(FIXP_DBL **quotaBuffer,
} }
/**************************************************************************/ /*****************************************************************************/
/*! /*!
\brief Do detection for one tonality estimate. \brief Detection for one tonality estimate.
This is the actual missing harmonics detection, using information from the
previous detection.
If a missing harmonic was detected (in a previous frame) due to too high
tonality differences, but there was not enough tonality difference in the
current frame, the detection algorithm still continues to trace the strongest
tone in the scalefactor band (assuming that this is the tone that is going to
be replaced in the decoder). This is done to avoid abrupt endings of sines
fading out (e.g. in the glockenspiel).
The function also tries to estimate where one sine is going to be replaced
with multiple sines (due to the patching). This is done by comparing the
tonality flatness measure of the original and the SBR signal.
The function also tries to estimate (for the scalefactor bands only
containing one qmf subband) when a strong tone in the original will be
replaced by a strong tone in the adjacent QMF subband.
\return none. \return none.
@ -694,10 +711,10 @@ static void detection(FIXP_DBL *quotaBuffer,
for(i=0;i<nSfb;i++){ for(i=0;i<nSfb;i++){
thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f))
? fixMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide) ? fMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide)
: mhThresh.thresHoldDiff; : mhThresh.thresHoldDiff;
thresTemp = fixMin(thresTemp, mhThresh.thresHoldDiff); thresTemp = fMin(thresTemp, mhThresh.thresHoldDiff);
if(pDiffVecScfb[i] > thresTemp){ if(pDiffVecScfb[i] > thresTemp){
pHarmVec[i] = 1; pHarmVec[i] = 1;
@ -813,8 +830,11 @@ static void detectionWithPrediction(FIXP_DBL **quotaBuffer,
if(newDetectionAllowed){ if(newDetectionAllowed){
/* Since we don't want to use the transient region for detection (since the tonality values
tend to be a bit unreliable for this region) the guide-values are copied to the current
starting point. */
if(totNoEst > 1){ if(totNoEst > 1){
start = detectionStart; start = detectionStart+1;
if (start != 0) { if (start != 0) {
FDKmemcpy(guideVectors[start].guideVectorDiff,guideVectors[0].guideVectorDiff,nSfb*sizeof(FIXP_DBL)); FDKmemcpy(guideVectors[start].guideVectorDiff,guideVectors[0].guideVectorDiff,nSfb*sizeof(FIXP_DBL));

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -268,8 +268,9 @@ qmfBasedNoiseFloorDetection(FIXP_DBL *noiseLevel, /*!< Pointer to v
/* /*
* Add a noise floor offset to compensate for bias in the detector * Add a noise floor offset to compensate for bias in the detector
*****************************************************************/ *****************************************************************/
if(!missingHarmonicFlag) if(!missingHarmonicFlag) {
*noiseLevel = fMult(*noiseLevel, noiseFloorOffset)<<(NOISE_FLOOR_OFFSET_SCALING); *noiseLevel = fixMin(fMult(*noiseLevel, noiseFloorOffset), (FIXP_DBL)MAXVAL_DBL>>NOISE_FLOOR_OFFSET_SCALING) << NOISE_FLOOR_OFFSET_SCALING;
}
/* /*
* check to see that we don't exceed the maximum allowed level * check to see that we don't exceed the maximum allowed level
@ -297,7 +298,7 @@ FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFlo
SCHAR *indexVector, /*!< Index vector to obtain the patched data. */ SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */ INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */
INT startIndex, /*!< Start index. */ INT startIndex, /*!< Start index. */
int numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */ UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
int transientFrame, /*!< A flag indicating if a transient is present. */ int transientFrame, /*!< A flag indicating if a transient is present. */
INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */ INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */
UINT sbrSyntaxFlags UINT sbrSyntaxFlags

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -119,7 +119,7 @@ FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFlo
SCHAR* indexVector, /*!< Index vector to obtain the patched data. */ SCHAR* indexVector, /*!< Index vector to obtain the patched data. */
INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */ INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */
INT startIndex, /*!< Start index. */ INT startIndex, /*!< Start index. */
int numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */ UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
INT transientFrame, /*!< A flag indicating if a transient is present. */ INT transientFrame, /*!< A flag indicating if a transient is present. */
INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */ INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */
UINT sbrSyntaxFlags UINT sbrSyntaxFlags

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -261,21 +261,23 @@ static const UINT opdDeltaTime_Code[] =
0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000006, 0000000000, 0x00000002, 0x00000003 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000006, 0000000000, 0x00000002, 0x00000003
}; };
static const INT psBands[] = static INT getNoBands(const INT mode)
{ {
PS_BANDS_COARSE, INT noBands = 0;
PS_BANDS_MID
};
static INT getNoBands(UINT mode) switch (mode) {
{ case 0: case 3: /* coarse */
if(mode>=6) noBands = PS_BANDS_COARSE;
return 0; break;
case 1: case 4: /* mid */
noBands = PS_BANDS_MID;
break;
case 2: case 5: /* fine not supported */
default: /* coarse as default */
noBands = PS_BANDS_COARSE;
}
if(mode>=3) return noBands;
mode = mode-3;
return psBands[mode];
} }
static INT getIIDRes(INT iidMode) static INT getIIDRes(INT iidMode)
@ -524,7 +526,7 @@ static INT encodeIpdOpd(HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeIpd( hBitBuf, bitCnt += FDKsbrEnc_EncodeIpd( hBitBuf,
psOut->ipd[env], psOut->ipd[env],
ipdLast, ipdLast,
getNoBands((UINT)psOut->iidMode), getNoBands(psOut->iidMode),
psOut->deltaIPD[env], psOut->deltaIPD[env],
&error); &error);
@ -532,7 +534,7 @@ static INT encodeIpdOpd(HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeOpd( hBitBuf, bitCnt += FDKsbrEnc_EncodeOpd( hBitBuf,
psOut->opd[env], psOut->opd[env],
opdLast, opdLast,
getNoBands((UINT)psOut->iidMode), getNoBands(psOut->iidMode),
psOut->deltaOPD[env], psOut->deltaOPD[env],
&error ); &error );
} }
@ -661,7 +663,7 @@ INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeIid( hBitBuf, bitCnt += FDKsbrEnc_EncodeIid( hBitBuf,
psOut->iid[env], psOut->iid[env],
iidLast, iidLast,
getNoBands((UINT)psOut->iidMode), getNoBands(psOut->iidMode),
(PS_IID_RESOLUTION)getIIDRes(psOut->iidMode), (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode),
psOut->deltaIID[env], psOut->deltaIID[env],
&error ); &error );
@ -677,7 +679,7 @@ INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeIcc( hBitBuf, bitCnt += FDKsbrEnc_EncodeIcc( hBitBuf,
psOut->icc[env], psOut->icc[env],
iccLast, iccLast,
getNoBands((UINT)psOut->iccMode), getNoBands(psOut->iccMode),
psOut->deltaICC[env], psOut->deltaICC[env],
&error); &error);

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur F<EFBFBD>derung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -149,21 +149,21 @@ typedef enum {
static const FIXP_DBL iidQuant_fx[15] = { static const FIXP_DBL iidQuant_fx[15] = {
0xce000000, 0xdc000000, 0xe4000000, 0xec000000, 0xf2000000, 0xf8000000, 0xfc000000, 0x00000000, (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000,
0x04000000, 0x08000000, 0x0e000000, 0x14000000, 0x1c000000, 0x24000000, 0x32000000 (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x14000000, (FIXP_DBL)0x1c000000, (FIXP_DBL)0x24000000, (FIXP_DBL)0x32000000
}; };
static const FIXP_DBL iidQuantFine_fx[31] = { static const FIXP_DBL iidQuantFine_fx[31] = {
0x9c000001, 0xa6000001, 0xb0000001, 0xba000001, 0xc4000000, 0xce000000, 0xd4000000, 0xda000000, (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001, (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000, (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000,
0xe0000000, 0xe6000000, 0xec000000, 0xf0000000, 0xf4000000, 0xf8000000, 0xfc000000, 0x00000000, (FIXP_DBL)0xe0000000, (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000, (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000,
0x04000000, 0x08000000, 0x0c000000, 0x10000000, 0x14000000, 0x1a000000, 0x20000000, 0x26000000, (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000, (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000,
0x2c000000, 0x32000000, 0x3c000000, 0x45ffffff, 0x4fffffff, 0x59ffffff, 0x63ffffff (FIXP_DBL)0x2c000000, (FIXP_DBL)0x32000000, (FIXP_DBL)0x3c000000, (FIXP_DBL)0x45ffffff, (FIXP_DBL)0x4fffffff, (FIXP_DBL)0x59ffffff, (FIXP_DBL)0x63ffffff
}; };
static const FIXP_DBL iccQuant[8] = { static const FIXP_DBL iccQuant[8] = {
0x7fffffff, 0x77ef9d7f, 0x6babc97f, 0x4ceaf27f, 0x2f0ed3c0, 0x00000000, 0xb49ba601, 0x80000000 (FIXP_DBL)0x7fffffff, (FIXP_DBL)0x77ef9d7f, (FIXP_DBL)0x6babc97f, (FIXP_DBL)0x4ceaf27f, (FIXP_DBL)0x2f0ed3c0, (FIXP_DBL)0x00000000, (FIXP_DBL)0xb49ba601, (FIXP_DBL)0x80000000
}; };
static FDK_PSENC_ERROR InitPSData( static FDK_PSENC_ERROR InitPSData(

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -122,6 +122,8 @@ amm-info@iis.fraunhofer.de
/************ Definitions ***************/ /************ Definitions ***************/
#define SBR_COMP_MODE_DELTA 0 #define SBR_COMP_MODE_DELTA 0
#define SBR_COMP_MODE_CTS 1 #define SBR_COMP_MODE_CTS 1
#define SBR_MAX_ENERGY_VALUES 5
#define SBR_GLOBAL_TONALITY_VALUES 2
#define MAX_NUM_CHANNELS 2 #define MAX_NUM_CHANNELS 2
@ -232,6 +234,8 @@ amm-info@iis.fraunhofer.de
#define FREQ 0 #define FREQ 0
#define TIME 1 #define TIME 1
/* qmf data scaling */
#define QMF_SCALE_OFFSET 7
/* huffman tables */ /* huffman tables */
#define CODE_BOOK_SCF_LAV00 60 #define CODE_BOOK_SCF_LAV00 60
@ -268,12 +272,4 @@ typedef enum
} }
INVF_MODE; INVF_MODE;
typedef enum
{
FREQ_RES_LOW = 0,
FREQ_RES_HIGH
}
FREQ_RES;
#endif #endif

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de
#define SBRENCODER_LIB_VL0 3 #define SBRENCODER_LIB_VL0 3
#define SBRENCODER_LIB_VL1 3 #define SBRENCODER_LIB_VL1 3
#define SBRENCODER_LIB_VL2 4 #define SBRENCODER_LIB_VL2 12
@ -170,7 +170,6 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
{ {
int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0; int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0;
UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE; UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
int isforThisCodec=0;
#define isForThisCore(i) \ #define isForThisCore(i) \
( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \ ( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \
@ -413,6 +412,23 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
config->codecSettings.transFac = transFac; config->codecSettings.transFac = transFac;
config->codecSettings.standardBitrate = standardBitrate; config->codecSettings.standardBitrate = standardBitrate;
if (bitRate < 28000) {
config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL;
config->threshold_AmpRes_FF_e = 7;
}
else if (bitRate >= 28000 && bitRate <= 48000) {
/* The float threshold is 75
0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore tonality are scaled by this
2/3 is because the original implementation divides the tonality values by 3, here it's divided by 2
128 compensates the necessary shiftfactor of 7 */
config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(75.0f*0.524288f/(2.0f/3.0f)/128.0f);
config->threshold_AmpRes_FF_e = 7;
}
else if (bitRate > 48000) {
config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0);
config->threshold_AmpRes_FF_e = 0;
}
if (bitRate==0) { if (bitRate==0) {
/* map vbr quality to bitrate */ /* map vbr quality to bitrate */
if (vbrMode < 30) if (vbrMode < 30)
@ -468,6 +484,57 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
config->stereoMode = sbrTuningTable[idx].stereoMode ; config->stereoMode = sbrTuningTable[idx].stereoMode ;
config->freqScale = sbrTuningTable[idx].freqScale ; config->freqScale = sbrTuningTable[idx].freqScale ;
if (numChannels == 1) {
/* stereo case */
switch (core) {
case AOT_AAC_LC:
if (bitRate <= (useSpeechConfig?24000U:20000U)) {
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
}
break;
case AOT_ER_AAC_ELD:
if (bitRate < 36000)
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
if (bitRate < 26000) {
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
}
break;
default:
break;
}
}
else {
/* stereo case */
switch (core) {
case AOT_AAC_LC:
if (bitRate <= 28000) {
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
}
break;
case AOT_ER_AAC_ELD:
if (bitRate < 72000) {
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
}
if (bitRate < 52000) {
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
}
break;
default:
break;
}
if (bitRate <= 28000) {
/*
additionally restrict frequency resolution in FIXFIX frames
to further reduce SBR payload size */
config->freq_res_fixfix[0] = FREQ_RES_LOW;
config->freq_res_fixfix[1] = FREQ_RES_LOW;
}
}
/* adjust usage of parametric coding dependent on bitrate and speech config flag */ /* adjust usage of parametric coding dependent on bitrate and speech config flag */
if (useSpeechConfig) if (useSpeechConfig)
config->parametricCoding = 0; config->parametricCoding = 0;
@ -516,6 +583,7 @@ static UINT
FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
INT downSampleFactor, INT downSampleFactor,
UINT codecGranuleLen UINT codecGranuleLen
,const INT isLowDelay
) )
{ {
if ( (downSampleFactor < 1 || downSampleFactor > 2) || if ( (downSampleFactor < 1 || downSampleFactor > 2) ||
@ -526,7 +594,11 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
config->useWaveCoding = 0; config->useWaveCoding = 0;
config->crcSbr = 0; config->crcSbr = 0;
config->dynBwSupported = 1; config->dynBwSupported = 1;
config->tran_thr = 13000; if (isLowDelay)
config->tran_thr = 6000;
else
config->tran_thr = 13000;
config->parametricCoding = 1; config->parametricCoding = 1;
config->sbrFrameSize = codecGranuleLen * downSampleFactor; config->sbrFrameSize = codecGranuleLen * downSampleFactor;
@ -559,7 +631,9 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
config->noiseFloorOffset = 0; config->noiseFloorOffset = 0;
config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */ config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */
config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */ config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */
config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */
config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */
config->fResTransIsLow = 0; /* for transient frames, set variable frequency resolution according to freqResTable */
/* header_extra_1 */ /* header_extra_1 */
config->freqScale = SBR_FREQ_SCALE_DEFAULT; config->freqScale = SBR_FREQ_SCALE_DEFAULT;
@ -854,7 +928,7 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
int clearOutput /*!< Do not consider any input signal */ int clearOutput /*!< Do not consider any input signal */
) )
{ {
HANDLE_SBR_ELEMENT hSbrElement = hEnvEncoder->sbrElement[iElement]; HANDLE_SBR_ELEMENT hSbrElement = NULL;
FDK_CRCINFO crcInfo; FDK_CRCINFO crcInfo;
INT crcReg; INT crcReg;
INT ch; INT ch;
@ -1207,7 +1281,10 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
FDK_ASSERT(params->e >= 0); FDK_ASSERT(params->e >= 0);
hEnv->encEnvData.freq_res_fixfix = 1; hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0];
hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1];
hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow;
hEnv->fLevelProtect = 0; hEnv->fLevelProtect = 0;
hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0; hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
@ -1349,11 +1426,29 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
e, e,
params->stat, params->stat,
timeSlots, timeSlots,
hEnv->encEnvData.freq_res_fixfix hEnv->encEnvData.freq_res_fixfix,
,hEnv->encEnvData.ldGrid hEnv->encEnvData.fResTransIsLow,
hEnv->encEnvData.ldGrid
); );
if(sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
{
INT bandwidth_qmf_slot = (sbrConfigData->sampleFreq>>1) / (sbrConfigData->noQmfBands);
if(FDKsbrEnc_InitSbrFastTransientDetector(
&hEnv->sbrFastTransientDetector,
sbrConfigData->noQmfSlots,
bandwidth_qmf_slot,
sbrConfigData->noQmfBands,
sbrConfigData->freqBandTable[0][0]
))
return(1);
}
/* The transient detector has to be initialized also if the fast transient
detector was active, because the values from the transient detector
structure are used. */
if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector, if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector,
sbrConfigData->sbrSyntaxFlags,
sbrConfigData->frameSize, sbrConfigData->frameSize,
sbrConfigData->sampleFreq, sbrConfigData->sampleFreq,
params, params,
@ -1553,12 +1648,6 @@ INT FDKsbrEnc_EnvInit (
hSbrElement->sbrConfigData.sbrSyntaxFlags = 0; hSbrElement->sbrConfigData.sbrSyntaxFlags = 0;
switch (aot) { switch (aot) {
case AOT_DRM_MPEG_PS:
case AOT_DRM_SBR:
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_SCALABLE;
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_DRM_CRC;
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
break;
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY;
break; break;
@ -1665,6 +1754,8 @@ INT FDKsbrEnc_EnvInit (
/* other switches */ /* other switches */
hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding; hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding; hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding;
hSbrElement->sbrConfigData.thresholdAmpResFF_m = params->threshold_AmpRes_FF_m;
hSbrElement->sbrConfigData.thresholdAmpResFF_e = params->threshold_AmpRes_FF_e;
/* init freq band table */ /* init freq band table */
if(updateFreqBandTable(&hSbrElement->sbrConfigData, if(updateFreqBandTable(&hSbrElement->sbrConfigData,
@ -1848,13 +1939,13 @@ INT sbrEncoder_Init(
if ( (aot==AOT_PS) || (aot==AOT_MP2_PS) || (aot==AOT_DABPLUS_PS) || (aot==AOT_DRM_MPEG_PS) ) { if ( aot==AOT_PS ) {
usePs = 1; usePs = 1;
} }
if ( (aot==AOT_ER_AAC_ELD) ) { if ( aot==AOT_ER_AAC_ELD ) {
lowDelay = 1; lowDelay = 1;
} }
else if ( (aot==AOT_ER_AAC_LD) ) { else if ( aot==AOT_ER_AAC_LD ) {
error = 1; error = 1;
goto bail; goto bail;
} }
@ -2006,7 +2097,8 @@ INT sbrEncoder_Init(
*/ */
if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el], if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el],
*downSampleFactor, *downSampleFactor,
coreFrameLength coreFrameLength,
IS_LOWDELAY(aot)
) ) ) )
{ {
error = 1; error = 1;
@ -2331,8 +2423,13 @@ INT sbrEncoder_GetLibInfo( LIB_INFO *info )
info->module_id = FDK_SBRENC; info->module_id = FDK_SBRENC;
info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2);
LIB_VERSION_STRING(info); LIB_VERSION_STRING(info);
#ifdef __ANDROID__
info->build_date = "";
info->build_time = "";
#else
info->build_date = __DATE__; info->build_date = __DATE__;
info->build_time = __TIME__; info->build_time = __TIME__;
#endif
info->title = "SBR Encoder"; info->title = "SBR Encoder";
/* Set flags */ /* Set flags */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -684,6 +684,9 @@ const sbrTuningTable_t sbrTuningTable[] =
/** AAC LOW DELAY SECTION **/ /** AAC LOW DELAY SECTION **/
/* 24 kHz dual rate - 12kHz singlerate is not allowed (deactivated in FDKsbrEnc_IsSbrSettingAvail()) */
{ CODEC_AACLD, 8000, 32000, 12000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */
/*** mono ***/ /*** mono ***/
/* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/ /* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/
{ CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s wrr: tuned */ { CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s wrr: tuned */
@ -702,10 +705,10 @@ const sbrTuningTable_t sbrTuningTable[] =
{ CODEC_AACLD, 52000, 64001, 22050, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */ { CODEC_AACLD, 52000, 64001, 22050, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */
/* 24/48 kHz dual rate */ /* 24/48 kHz dual rate */
{ CODEC_AACLD, 20000, 22000, 24000, 1, 4, 1, 8, 4, 2, 3, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ { CODEC_AACLD, 20000, 22000, 24000, 1, 3, 4, 8, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
{ CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ { CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ { CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
{ CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ { CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 8, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ CODEC_AACLD, 56000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 kbit/s */ { CODEC_AACLD, 56000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 kbit/s */
/* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */ /* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */
@ -722,7 +725,7 @@ const sbrTuningTable_t sbrTuningTable[] =
{ CODEC_AACLD, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ { CODEC_AACLD, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */
/* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR */ /* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR */
{ CODEC_AACLD, 36000, 60000, 48000, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */ { CODEC_AACLD, 36000, 60000, 48000, 1, 4, 7, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* nominal: 40 */
{ CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */ { CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */
{ CODEC_AACLD, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */ { CODEC_AACLD, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */
{ CODEC_AACLD, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ { CODEC_AACLD, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -682,7 +682,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
/* /*
Reset the patching and allocate memory for the quota matrix. Reset the patching and allocate memory for the quota matrix.
Assing parameters for the LPC analysis. Assuming parameters for the LPC analysis.
*/ */
if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
switch (timeSlots) { switch (timeSlots) {
@ -690,7 +690,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
hTonCorr->lpcLength[0] = 8 - LPC_ORDER; hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
hTonCorr->lpcLength[1] = 7 - LPC_ORDER; hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7; hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */
hTonCorr->frameStartIndexInvfEst = 0; hTonCorr->frameStartIndexInvfEst = 0;
hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
break; break;
@ -698,7 +698,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
hTonCorr->lpcLength[0] = 8 - LPC_ORDER; hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
hTonCorr->lpcLength[1] = 8 - LPC_ORDER; hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8; hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */
hTonCorr->frameStartIndexInvfEst = 0; hTonCorr->frameStartIndexInvfEst = 0;
hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
break; break;

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -118,7 +118,7 @@ typedef struct
INT bufferLength; /*!< Length of the r and i buffers. */ INT bufferLength; /*!< Length of the r and i buffers. */
INT stepSize; /*!< Stride for the lpc estimate. */ INT stepSize; /*!< Stride for the lpc estimate. */
INT numberOfEstimates; /*!< The total number of estiamtes, available in the quotaMatrix.*/ INT numberOfEstimates; /*!< The total number of estiamtes, available in the quotaMatrix.*/
INT numberOfEstimatesPerFrame; /*!< The number of estimates per frame available in the quotaMatrix.*/ UINT numberOfEstimatesPerFrame; /*!< The number of estimates per frame available in the quotaMatrix.*/
INT lpcLength[2]; /*!< Segment length used for second order LPC analysis.*/ INT lpcLength[2]; /*!< Segment length used for second order LPC analysis.*/
INT nextSample; /*!< Where to start the LPC analysis of the current frame.*/ INT nextSample; /*!< Where to start the LPC analysis of the current frame.*/
INT move; /*!< How many estimates to move in the quotaMatrix, when buffering. */ INT move; /*!< How many estimates to move in the quotaMatrix, when buffering. */

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -89,7 +89,7 @@ amm-info@iis.fraunhofer.de
#include "genericStds.h" #include "genericStds.h"
#define NORM_QMF_ENERGY 5.684341886080801486968994140625e-14 /* 2^-44 */ #define NORM_QMF_ENERGY 9.31322574615479E-10 /* 2^-30 */
/* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */ /* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */
#define ABS_THRES ((FIXP_DBL)16) #define ABS_THRES ((FIXP_DBL)16)
@ -106,22 +106,30 @@ amm-info@iis.fraunhofer.de
\return calculated value \return calculated value
*******************************************************************************/ *******************************************************************************/
#define NRG_SHIFT 3 /* for energy summation */
static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS],
INT *scaleEnergies, INT *scaleEnergies,
FIXP_DBL EnergyTotal, FIXP_DBL EnergyTotal,
INT nSfb, INT nSfb,
INT start, INT start,
INT border, INT border,
INT stop) INT YBufferWriteOffset,
INT stop,
INT *result_e)
{ {
INT i,j; INT i,j;
INT len1,len2; INT len1,len2;
FIXP_DBL delta,tmp0,tmp1,tmp2; SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e=19, energies_e_add;
FIXP_DBL accu1,accu2,delta_sum,result; SCHAR prevEnergies_e_diff, newEnergies_e_diff;
FIXP_DBL tmp0,tmp1;
FIXP_DBL accu1,accu2,accu1_init,accu2_init;
FIXP_DBL delta, delta_sum;
INT accu_e, tmp_e;
FDK_ASSERT(scaleEnergies[0] >= 0); delta_sum = FL2FXCONST_DBL(0.0f);
*result_e = 0;
/* equal for aac (would be not equal for mp3) */
len1 = border-start; len1 = border-start;
len2 = stop-border; len2 = stop-border;
@ -130,43 +138,91 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
pos_weight = FL2FXCONST_DBL(0.5f) - (len1*GetInvInt(len1+len2)); pos_weight = FL2FXCONST_DBL(0.5f) - (len1*GetInvInt(len1+len2));
pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - (fMult(pos_weight, pos_weight)<<2); pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - (fMult(pos_weight, pos_weight)<<2);
delta_sum = FL2FXCONST_DBL(0.0f); /*** Calc scaling for energies ***/
FDK_ASSERT(scaleEnergies[0] >= 0);
FDK_ASSERT(scaleEnergies[1] >= 0);
energies_e = 19 - FDKmin(scaleEnergies[0], scaleEnergies[1]);
/* limit shift for energy accumulation, energies_e can be -10 min. */
if (energies_e < -10) {
energies_e_add = -10 - energies_e;
energies_e = -10;
} else if (energies_e > 17) {
energies_e_add = energies_e - 17;
energies_e = 17;
} else {
energies_e_add = 0;
}
/* compensate scaling differences between scaleEnergies[0] and scaleEnergies[1] */
prevEnergies_e_diff = scaleEnergies[0] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
newEnergies_e_diff = scaleEnergies[1] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
prevEnergies_e_diff = fMin(prevEnergies_e_diff, DFRACT_BITS-1);
newEnergies_e_diff = fMin(newEnergies_e_diff, DFRACT_BITS-1);
for (i=start; i<YBufferWriteOffset; i++) {
energies_e_diff[i] = prevEnergies_e_diff;
}
for (i=YBufferWriteOffset; i<stop; i++) {
energies_e_diff[i] = newEnergies_e_diff;
}
/* Sum up energies of all QMF-timeslots for both halfs */ /* Sum up energies of all QMF-timeslots for both halfs */
FDK_ASSERT(len1<=8); /* otherwise an overflow is possible */
FDK_ASSERT(len2<=8); /* otherwise an overflow is possible */
/* init with some energy to prevent division by zero
and to prevent splitting for very low levels */
accu1_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
accu2_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
accu1_init = fMult(accu1_init, (FIXP_DBL)len1<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
accu2_init = fMult(accu2_init, (FIXP_DBL)len2<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
for (j=0; j<nSfb; j++) { for (j=0; j<nSfb; j++) {
#define NRG_SCALE 3
/* init with some energy to prevent division by zero accu1 = accu1_init;
and to prevent splitting for very low levels */ accu2 = accu2_init;
accu1 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* complex init for compare with original version */ accu_e = energies_e+3;
accu2 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* can be simplified in dsp implementation */
/* Sum up energies in first half */ /* Sum up energies in first half */
for (i=start; i<border; i++) { for (i=start; i<border; i++) {
accu1 += (Energies[i][j]>>NRG_SCALE); accu1 += scaleValue(Energies[i][j], -energies_e_diff[i]);
} }
/* Sum up energies in second half */ /* Sum up energies in second half */
for (i=border; i<stop; i++) { for (i=border; i<stop; i++) {
accu2 += (Energies[i][j]>>NRG_SCALE); accu2 += scaleValue(Energies[i][j], -energies_e_diff[i]);
} }
/* Energy change in current band */ /* Energy change in current band */
tmp0 = CalcLdData(accu2); #define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */
tmp1 = CalcLdData(accu1); tmp0 = fLog2(accu2, accu_e) - fLog2(accu1, accu_e);
tmp2 = (tmp0 - tmp1 + CalcLdData(len1)-CalcLdData(len2)); tmp1 = fLog2((FIXP_DBL)len1, 31) - fLog2((FIXP_DBL)len2, 31);
delta = fixp_abs(fMult(tmp2, FL2FXCONST_DBL(0.6931471806f))); delta = fMult(LN2, (tmp0 + tmp1));
delta = (FIXP_DBL)FDKabs( delta );
/* Weighting with amplitude ratio of this band */ /* Weighting with amplitude ratio of this band */
result = (EnergyTotal == FL2FXCONST_DBL(0.0f)) accu_e++;
? FL2FXCONST_DBL(0.f) accu1>>=1;
: FDKsbrEnc_LSI_divide_scale_fract( (accu1+accu2), accu2>>=1;
(EnergyTotal>>NRG_SCALE)+(FIXP_DBL)1, if (accu_e & 1) {
(FIXP_DBL)MAXVAL_DBL >> fixMin(scaleEnergies[0],(DFRACT_BITS-1)) ); accu_e++;
accu1>>=1;
accu2>>=1;
}
delta_sum += (FIXP_DBL)(fMult(sqrtFixp(result), delta)); delta_sum += fMult(sqrtFixp(accu1+accu2), delta);
*result_e = ((accu_e>>1) + LD_DATA_SHIFT);
} }
energyTotal_e+=1; /* for a defined square result exponent, the exponent has to be even */
EnergyTotal<<=1;
delta_sum = fMult(delta_sum, invSqrtNorm2(EnergyTotal, &tmp_e));
*result_e = *result_e + (tmp_e-(energyTotal_e>>1));
return fMult(delta_sum, pos_weight); return fMult(delta_sum, pos_weight);
} }
@ -175,9 +231,12 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
******************************************************************************* *******************************************************************************
\brief Calculates total lowband energy \brief Calculates total lowband energy
The return value nrgTotal is scaled by the factor (1/32.0) The input values Energies[0] (low-band) are scaled by the factor
2^(14-*scaleEnergies[0])
The input values Energies[1] (high-band) are scaled by the factor
2^(14-*scaleEnergies[1])
\return total energy in the lowband \return total energy in the lowband, scaled by the factor 2^19
*******************************************************************************/ *******************************************************************************/
static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
int *scaleEnergies, int *scaleEnergies,
@ -194,6 +253,7 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
int ts,k; int ts,k;
/* Sum up lowband energy from one frame at offset tran_off */ /* Sum up lowband energy from one frame at offset tran_off */
/* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */
for (ts=tran_offdiv2; ts<YBufferWriteOffset; ts++) { for (ts=tran_offdiv2; ts<YBufferWriteOffset; ts++) {
for (k = 0; k < freqBandTable[0]; k++) { for (k = 0; k < freqBandTable[0]; k++) {
accu1 += Energies[ts][k] >> 6; accu1 += Energies[ts][k] >> 6;
@ -201,12 +261,12 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
} }
for (; ts<tran_offdiv2+(slots>>nrgSzShift); ts++) { for (; ts<tran_offdiv2+(slots>>nrgSzShift); ts++) {
for (k = 0; k < freqBandTable[0]; k++) { for (k = 0; k < freqBandTable[0]; k++) {
accu2 += Energies[ts][k] >> 6; accu2 += Energies[ts][k] >> 9;
} }
} }
nrgTotal = ( (accu1 >> fixMin(scaleEnergies[0],(DFRACT_BITS-1))) nrgTotal = ( scaleValueSaturate(accu1, 1-scaleEnergies[0]) )
+ (accu2 >> fixMin(scaleEnergies[1],(DFRACT_BITS-1))) ) << (2); + ( scaleValueSaturate(accu2, 4-scaleEnergies[1]) );
return(nrgTotal); return(nrgTotal);
} }
@ -222,21 +282,23 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
is 1 SBR-band. Therefore the data to be fed into the spectralChange is 1 SBR-band. Therefore the data to be fed into the spectralChange
function is reduced. function is reduced.
The values EnergiesM are scaled by the factor (1/32.0) and scaleEnergies[0] The values EnergiesM are scaled by the factor (2^19-scaleEnergies[0]) for
The return value nrgTotal is scaled by the factor (1/32.0) slots<YBufferWriteOffset and by the factor (2^19-scaleEnergies[1]) for
slots>=YBufferWriteOffset.
\return total energy in the highband \return total energy in the highband, scaled by factor 2^19
*******************************************************************************/ *******************************************************************************/
static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
INT *scaleEnergies, INT *scaleEnergies,
INT YBufferWriteOffset,
FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], /*!< Combined output */ FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], /*!< Combined output */
UCHAR *RESTRICT freqBandTable, UCHAR *RESTRICT freqBandTable,
INT nSfb, INT nSfb,
INT sbrSlots, INT sbrSlots,
INT timeStep) INT timeStep)
{ {
INT i,j,k,slotIn,slotOut,scale; INT i,j,k,slotIn,slotOut,scale[2];
INT li,ui; INT li,ui;
FIXP_DBL nrgTotal; FIXP_DBL nrgTotal;
FIXP_DBL accu = FL2FXCONST_DBL(0.0f); FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
@ -245,7 +307,7 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
combine QMF-bands to SBR-bands, combine QMF-bands to SBR-bands,
combine Left and Right channel */ combine Left and Right channel */
for (slotOut=0; slotOut<sbrSlots; slotOut++) { for (slotOut=0; slotOut<sbrSlots; slotOut++) {
slotIn = 2*slotOut; slotIn = timeStep*slotOut;
for (j=0; j<nSfb; j++) { for (j=0; j<nSfb; j++) {
accu = FL2FXCONST_DBL(0.0f); accu = FL2FXCONST_DBL(0.0f);
@ -262,19 +324,29 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
} }
} }
scale = fixMin(8,scaleEnergies[0]); /* scale energies down before add up */ /* scale energies down before add up */
scale[0] = fixMin(8,scaleEnergies[0]);
scale[1] = fixMin(8,scaleEnergies[1]);
if ((scaleEnergies[0]-1) > (DFRACT_BITS-1) ) if ((scaleEnergies[0]-scale[0]) > (DFRACT_BITS-1) || (scaleEnergies[1]-scale[0]) > (DFRACT_BITS-1))
nrgTotal = FL2FXCONST_DBL(0.0f); nrgTotal = FL2FXCONST_DBL(0.0f);
else { else {
/* Now add all energies */ /* Now add all energies */
accu = FL2FXCONST_DBL(0.0f); accu = FL2FXCONST_DBL(0.0f);
for (slotOut=0; slotOut<sbrSlots; slotOut++) {
for (slotOut=0; slotOut<YBufferWriteOffset; slotOut++) {
for (j=0; j<nSfb; j++) { for (j=0; j<nSfb; j++) {
accu += (EnergiesM[slotOut][j] >> scale); accu += (EnergiesM[slotOut][j] >> scale[0]);
} }
} }
nrgTotal = accu >> (scaleEnergies[0]-scale); nrgTotal = accu >> (scaleEnergies[0]-scale[0]);
for (slotOut=YBufferWriteOffset; slotOut<sbrSlots; slotOut++) {
for (j=0; j<nSfb; j++) {
accu += (EnergiesM[slotOut][j] >> scale[0]);
}
}
nrgTotal = accu >> (scaleEnergies[1]-scale[1]);
} }
return(nrgTotal); return(nrgTotal);
@ -299,18 +371,23 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
int YBufferSzShift, int YBufferSzShift,
int nSfb, int nSfb,
int timeStep, int timeStep,
int no_cols) int no_cols,
FIXP_DBL* tonality)
{ {
if (tran_vector[1]==0) /* no transient was detected */ if (tran_vector[1]==0) /* no transient was detected */
{ {
FIXP_DBL delta; FIXP_DBL delta;
FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS]; INT delta_e;
FIXP_DBL (*EnergiesM)[MAX_FREQ_COEFFS];
FIXP_DBL EnergyTotal,newLowbandEnergy,newHighbandEnergy; FIXP_DBL EnergyTotal,newLowbandEnergy,newHighbandEnergy;
INT border; INT border;
INT sbrSlots = fMultI(GetInvInt(timeStep),no_cols); INT sbrSlots = fMultI(GetInvInt(timeStep),no_cols);
C_ALLOC_SCRATCH_START(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
FDK_ASSERT( sbrSlots * timeStep == no_cols ); FDK_ASSERT( sbrSlots * timeStep == no_cols );
EnergiesM = (FIXP_DBL(*)[MAX_FREQ_COEFFS])_EnergiesM;
/* /*
Get Lowband-energy over a range of 2 frames (Look half a frame back and ahead). Get Lowband-energy over a range of 2 frames (Look half a frame back and ahead).
*/ */
@ -324,16 +401,13 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
newHighbandEnergy = addHighbandEnergies(Energies, newHighbandEnergy = addHighbandEnergies(Energies,
scaleEnergies, scaleEnergies,
YBufferWriteOffset,
EnergiesM, EnergiesM,
freqBandTable, freqBandTable,
nSfb, nSfb,
sbrSlots, sbrSlots,
timeStep); timeStep);
if ( h_sbrTransientDetector->frameShift != 0 ) {
if (tran_vector[1]==0)
tran_vector[0] = 0;
} else
{ {
/* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame look-behind /* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame look-behind
newLowbandEnergy: Corresponds to 1 frame, starting in the middle of the current frame */ newLowbandEnergy: Corresponds to 1 frame, starting in the middle of the current frame */
@ -343,23 +417,39 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
of a FIXFIX-frame with 2 envelopes. */ of a FIXFIX-frame with 2 envelopes. */
border = (sbrSlots+1) >> 1; border = (sbrSlots+1) >> 1;
if ( (INT)EnergyTotal&0xffffffe0 && (scaleEnergies[0]<32 || scaleEnergies[1]<32) ) /* i.e. > 31 */ {
delta = spectralChange(EnergiesM, delta = spectralChange(EnergiesM,
scaleEnergies, scaleEnergies,
EnergyTotal, EnergyTotal,
nSfb, nSfb,
0, 0,
border, border,
sbrSlots); YBufferWriteOffset,
sbrSlots,
&delta_e
);
} else {
delta = FL2FXCONST_DBL(0.0f);
delta_e = 0;
if (delta > (h_sbrTransientDetector->split_thr >> LD_DATA_SHIFT)) /* delta scaled by 1/64 */ /* set tonality to 0 when energy is very low, since the amplitude
resolution should then be low as well */
*tonality = FL2FXCONST_DBL(0.0f);
}
if ( fIsLessThan(h_sbrTransientDetector->split_thr_m, h_sbrTransientDetector->split_thr_e, delta, delta_e) ) {
tran_vector[0] = 1; /* Set flag for splitting */ tran_vector[0] = 1; /* Set flag for splitting */
else } else {
tran_vector[0] = 0; tran_vector[0] = 0;
}
} }
/* Update prevLowBandEnergy */ /* Update prevLowBandEnergy */
h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy; h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy;
h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy; h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy;
C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
} }
} }
@ -636,6 +726,7 @@ FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran,
int int
FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
INT frameSize, INT frameSize,
INT sampleFreq, INT sampleFreq,
sbrConfigurationPtr params, sbrConfigurationPtr params,
@ -649,8 +740,8 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
{ {
INT totalBitrate = params->codecSettings.standardBitrate * params->codecSettings.nChannels; INT totalBitrate = params->codecSettings.standardBitrate * params->codecSettings.nChannels;
INT codecBitrate = params->codecSettings.bitRate; INT codecBitrate = params->codecSettings.bitRate;
FIXP_DBL bitrateFactor_fix, framedur_fix; FIXP_DBL bitrateFactor_m, framedur_fix;
INT scale_0, scale_1; INT bitrateFactor_e, tmp_e;
FDKmemclear(h_sbrTransientDetector,sizeof(SBR_TRANSIENT_DETECTOR)); FDKmemclear(h_sbrTransientDetector,sizeof(SBR_TRANSIENT_DETECTOR));
@ -658,11 +749,12 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
h_sbrTransientDetector->tran_off = tran_off; h_sbrTransientDetector->tran_off = tran_off;
if(codecBitrate) { if(codecBitrate) {
bitrateFactor_fix = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&scale_0); bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&bitrateFactor_e);
bitrateFactor_e += 2;
} }
else { else {
bitrateFactor_fix = FL2FXCONST_DBL(1.0/4.0); bitrateFactor_m = FL2FXCONST_DBL(1.0/4.0);
scale_0 = 0; bitrateFactor_e = 2;
} }
framedur_fix = fDivNorm(frameSize, sampleFreq); framedur_fix = fDivNorm(frameSize, sampleFreq);
@ -674,9 +766,13 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010); FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010);
tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001)); tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001));
tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &scale_1); tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e);
scale_1 = -(scale_1 + scale_0 + 2); bitrateFactor_e = (tmp_e + bitrateFactor_e);
if(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
bitrateFactor_e--; /* divide by 2 */
}
FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS); FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS);
FDK_ASSERT(no_rows <= QMF_CHANNELS); FDK_ASSERT(no_rows <= QMF_CHANNELS);
@ -684,14 +780,8 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
h_sbrTransientDetector->no_cols = no_cols; h_sbrTransientDetector->no_cols = no_cols;
h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows); h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows);
h_sbrTransientDetector->tran_fc = tran_fc; h_sbrTransientDetector->tran_fc = tran_fc;
h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m);
if (scale_1>=0) { h_sbrTransientDetector->split_thr_e = bitrateFactor_e;
h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) >> scale_1;
}
else {
h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) << (-scale_1);
}
h_sbrTransientDetector->no_rows = no_rows; h_sbrTransientDetector->no_rows = no_rows;
h_sbrTransientDetector->mode = params->tran_det_mode; h_sbrTransientDetector->mode = params->tran_det_mode;
h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f); h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f);
@ -699,3 +789,281 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
return (0); return (0);
} }
#define ENERGY_SCALING_SIZE 32
INT FDKsbrEnc_InitSbrFastTransientDetector(
HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
const INT time_slots_per_frame,
const INT bandwidth_qmf_slot,
const INT no_qmf_channels,
const INT sbr_qmf_1st_band
)
{
int i, e;
int buff_size;
FIXP_DBL myExp;
FIXP_DBL myExpSlot;
h_sbrFastTransientDetector->lookahead = TRAN_DET_LOOKAHEAD;
h_sbrFastTransientDetector->nTimeSlots = time_slots_per_frame;
buff_size = h_sbrFastTransientDetector->nTimeSlots + h_sbrFastTransientDetector->lookahead;
for(i=0; i< buff_size; i++) {
h_sbrFastTransientDetector->delta_energy[i] = FL2FXCONST_DBL(0.0f);
h_sbrFastTransientDetector->energy_timeSlots[i] = FL2FXCONST_DBL(0.0f);
h_sbrFastTransientDetector->lowpass_energy[i] = FL2FXCONST_DBL(0.0f);
h_sbrFastTransientDetector->transientCandidates[i] = 0;
}
FDK_ASSERT(bandwidth_qmf_slot > 0.f);
h_sbrFastTransientDetector->stopBand = fMin(TRAN_DET_STOP_FREQ/bandwidth_qmf_slot, no_qmf_channels);
h_sbrFastTransientDetector->startBand = fMin(sbr_qmf_1st_band, h_sbrFastTransientDetector->stopBand - TRAN_DET_MIN_QMFBANDS);
FDK_ASSERT(h_sbrFastTransientDetector->startBand < no_qmf_channels);
FDK_ASSERT(h_sbrFastTransientDetector->startBand < h_sbrFastTransientDetector->stopBand);
FDK_ASSERT(h_sbrFastTransientDetector->startBand > 1);
FDK_ASSERT(h_sbrFastTransientDetector->stopBand > 1);
/* the energy weighting and adding up has a headroom of 6 Bits,
so up to 64 bands can be added without potential overflow. */
FDK_ASSERT(h_sbrFastTransientDetector->stopBand - h_sbrFastTransientDetector->startBand <= 64);
/* QMF_HP_dB_SLOPE_FIX says that we want a 20 dB per 16 kHz HP filter.
The following lines map this to the QMF bandwidth. */
#define EXP_E 7 /* QMF_CHANNELS (=64) multiplications max, max. allowed sum is 0.5 */
myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, (FIXP_DBL)bandwidth_qmf_slot, &e);
myExp = scaleValueSaturate(myExp, e+0+DFRACT_BITS-1-EXP_E);
myExpSlot = myExp;
for(i=0; i<QMF_CHANNELS; i++){
/* Calculate dBf over all qmf bands:
dBf = (10^(0.002266f/10*bw(slot)))^(band) =
= 2^(log2(10)*0.002266f/10*bw(slot)*band) =
= 2^(0.00075275f*bw(slot)*band) */
FIXP_DBL dBf_m; /* dBf mantissa */
INT dBf_e; /* dBf exponent */
INT tmp;
INT dBf_int; /* dBf integer part */
FIXP_DBL dBf_fract; /* dBf fractional part */
/* myExp*(i+1) = myExp_int - myExp_fract
myExp*(i+1) is split up here for better accuracy of CalcInvLdData(),
for its result can be split up into an integer and a fractional part */
/* Round up to next integer */
FIXP_DBL myExp_int = (myExpSlot & (FIXP_DBL)0xfe000000) + (FIXP_DBL)0x02000000;
/* This is the fractional part that needs to be substracted */
FIXP_DBL myExp_fract = myExp_int - myExpSlot;
/* Calc integer part */
dBf_int = CalcInvLdData(myExp_int);
/* The result needs to be re-scaled. The ld(myExp_int) had been scaled by EXP_E,
the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
Therefore, the correctly scaled result is dBf_int^(2^(EXP_E-LD_DATA_SHIFT)),
which is dBf_int^2 */
dBf_int *= dBf_int;
/* Calc fractional part */
dBf_fract = CalcInvLdData(-myExp_fract);
/* The result needs to be re-scaled. The ld(myExp_fract) had been scaled by EXP_E,
the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
Therefore, the correctly scaled result is dBf_fract^(2^(EXP_E-LD_DATA_SHIFT)),
which is dBf_fract^2 */
dBf_fract = fMultNorm(dBf_fract, dBf_fract, &tmp);
/* Get worst case scaling of multiplication result */
dBf_e = (DFRACT_BITS-1 - tmp) - CountLeadingBits(dBf_int);
/* Now multiply integer with fractional part of the result, thus resulting
in the overall accurate fractional result */
dBf_m = fMultNorm(dBf_int, dBf_fract, &e);
dBf_m = scaleValueSaturate(dBf_m, e+DFRACT_BITS-1+tmp-dBf_e);
myExpSlot += myExp;
/* Keep the results */
h_sbrFastTransientDetector->dBf_m[i] = dBf_m;
h_sbrFastTransientDetector->dBf_e[i] = dBf_e;
}
/* Make sure that dBf is greater than 1.0 (because it should be a highpass) */
/* ... */
return 0;
}
void FDKsbrEnc_fastTransientDetect(
const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
const FIXP_DBL *const *Energies,
const int *const scaleEnergies,
const INT YBufferWriteOffset,
UCHAR *const tran_vector
)
{
int timeSlot, band;
FIXP_DBL max_delta_energy; /* helper to store maximum energy ratio */
int max_delta_energy_scale; /* helper to store scale of maximum energy ratio */
int ind_max = 0; /* helper to store index of maximum energy ratio */
int isTransientInFrame = 0;
const int nTimeSlots = h_sbrFastTransientDetector->nTimeSlots;
const int lookahead = h_sbrFastTransientDetector->lookahead;
const int startBand = h_sbrFastTransientDetector->startBand;
const int stopBand = h_sbrFastTransientDetector->stopBand;
int * transientCandidates = h_sbrFastTransientDetector->transientCandidates;
FIXP_DBL * energy_timeSlots = h_sbrFastTransientDetector->energy_timeSlots;
int * energy_timeSlots_scale = h_sbrFastTransientDetector->energy_timeSlots_scale;
FIXP_DBL * delta_energy = h_sbrFastTransientDetector->delta_energy;
int * delta_energy_scale = h_sbrFastTransientDetector->delta_energy_scale;
const FIXP_DBL thr = TRAN_DET_THRSHLD;
const INT thr_scale = TRAN_DET_THRSHLD_SCALE;
/*reset transient info*/
tran_vector[2] = 0;
/* reset transient candidates */
FDKmemclear(transientCandidates+lookahead, nTimeSlots*sizeof(int));
for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
int i, norm;
FIXP_DBL tmpE = FL2FXCONST_DBL(0.0f);
int headroomEnSlot = DFRACT_BITS-1;
FIXP_DBL smallNRG = FL2FXCONST_DBL(1e-2f);
FIXP_DBL denominator;
INT denominator_scale;
/* determine minimum headroom of energy values for this timeslot */
for(band = startBand; band < stopBand; band++) {
int tmp_headroom = fNormz(Energies[timeSlot][band])-1;
if(tmp_headroom < headroomEnSlot){
headroomEnSlot = tmp_headroom;
}
}
for(i = 0, band = startBand; band < stopBand; band++, i++) {
/* energy is weighted by weightingfactor stored in dBf_m array */
/* dBf_m index runs from 0 to stopBand-startband */
/* energy shifted by calculated headroom for maximum precision */
FIXP_DBL weightedEnergy = fMult(Energies[timeSlot][band]<<headroomEnSlot, h_sbrFastTransientDetector->dBf_m[i]);
/* energy is added up */
/* shift by 6 to have a headroom for maximum 64 additions */
/* shift by dBf_e to handle weighting factor dependent scale factors */
tmpE += weightedEnergy >> (6 + (10 - h_sbrFastTransientDetector->dBf_e[i]));
}
/* store calculated energy for timeslot */
energy_timeSlots[timeSlot] = tmpE;
/* calculate overall scale factor for energy of this timeslot */
/* = original scale factor of energies (-scaleEnergies[0]+2*QMF_SCALE_OFFSET or -scaleEnergies[1]+2*QMF_SCALE_OFFSET */
/* depending on YBufferWriteOffset) */
/* + weighting factor scale (10) */
/* + adding up scale factor ( 6) */
/* - headroom of energy value (headroomEnSlot) */
if(timeSlot < YBufferWriteOffset){
energy_timeSlots_scale[timeSlot] = (-scaleEnergies[0]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
} else {
energy_timeSlots_scale[timeSlot] = (-scaleEnergies[1]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
}
/* Add a small energy to the denominator, thus making the transient
detection energy-dependent. Loud transients are being detected,
silent ones not. */
/* make sure that smallNRG does not overflow */
if ( -energy_timeSlots_scale[timeSlot-1] + 1 > 5 )
{
denominator = smallNRG;
denominator_scale = 0;
} else {
/* Leave an additional headroom of 1 bit for this addition. */
smallNRG = scaleValue(smallNRG, -(energy_timeSlots_scale[timeSlot-1] + 1));
denominator = (energy_timeSlots[timeSlot-1]>>1) + smallNRG;
denominator_scale = energy_timeSlots_scale[timeSlot-1]+1;
}
delta_energy[timeSlot] = fDivNorm(energy_timeSlots[timeSlot], denominator, &norm);
delta_energy_scale[timeSlot] = energy_timeSlots_scale[timeSlot] - denominator_scale + norm;
}
/*get transient candidates*/
/* For every timeslot, check if delta(E) exceeds the threshold. If it did,
it could potentially be marked as a transient candidate. However, the 2
slots before the current one must not be transients with an energy higher
than 1.4*E(current). If both aren't transients or if the energy of the
current timesolot is more than 1.4 times higher than the energy in the
last or the one before the last slot, it is marked as a transient.*/
FDK_ASSERT(lookahead >= 2);
for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
FIXP_DBL energy_cur_slot_weighted = fMult(energy_timeSlots[timeSlot],FL2FXCONST_DBL(1.0f/1.4f));
if( !fIsLessThan(delta_energy[timeSlot], delta_energy_scale[timeSlot], thr, thr_scale) &&
( ((transientCandidates[timeSlot-2]==0) && (transientCandidates[timeSlot-1]==0)) ||
!fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-1], energy_timeSlots_scale[timeSlot-1] ) ||
!fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-2], energy_timeSlots_scale[timeSlot-2] )
)
)
{
/* in case of strong transients, subsequent
* qmf slots might be recognized as transients. */
transientCandidates[timeSlot] = 1;
}
}
/*get transient with max energy*/
max_delta_energy = FL2FXCONST_DBL(0.0f);
max_delta_energy_scale = 0;
ind_max = 0;
isTransientInFrame = 0;
for(timeSlot = 0; timeSlot < nTimeSlots; timeSlot++) {
int scale = fMax(delta_energy_scale[timeSlot], max_delta_energy_scale);
if(transientCandidates[timeSlot] && ( (delta_energy[timeSlot] >> (scale - delta_energy_scale[timeSlot])) > (max_delta_energy >> (scale - max_delta_energy_scale)) ) ) {
max_delta_energy = delta_energy[timeSlot];
max_delta_energy_scale = scale;
ind_max = timeSlot;
isTransientInFrame = 1;
}
}
/*from all transient candidates take the one with the biggest energy*/
if(isTransientInFrame) {
tran_vector[0] = ind_max;
tran_vector[1] = 1;
} else {
/*reset transient info*/
tran_vector[0] = tran_vector[1] = 0;
}
/*check for transients in lookahead*/
for(timeSlot = nTimeSlots; timeSlot < nTimeSlots + lookahead; timeSlot++) {
if(transientCandidates[timeSlot]) {
tran_vector[2] = 1;
}
}
/*update buffers*/
for(timeSlot = 0; timeSlot < lookahead; timeSlot++) {
transientCandidates[timeSlot] = transientCandidates[nTimeSlots + timeSlot];
/* fixpoint stuff */
energy_timeSlots[timeSlot] = energy_timeSlots[nTimeSlots + timeSlot];
energy_timeSlots_scale[timeSlot] = energy_timeSlots_scale[nTimeSlots + timeSlot];
delta_energy[timeSlot] = delta_energy[nTimeSlots + timeSlot];
delta_energy_scale[timeSlot] = delta_energy_scale[nTimeSlots + timeSlot];
}
}

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -96,7 +96,8 @@ typedef struct
FIXP_DBL transients[QMF_MAX_TIME_SLOTS+(QMF_MAX_TIME_SLOTS/2)]; FIXP_DBL transients[QMF_MAX_TIME_SLOTS+(QMF_MAX_TIME_SLOTS/2)];
FIXP_DBL thresholds[QMF_CHANNELS]; FIXP_DBL thresholds[QMF_CHANNELS];
FIXP_DBL tran_thr; /* Master threshold for transient signals */ FIXP_DBL tran_thr; /* Master threshold for transient signals */
FIXP_DBL split_thr; /* Threshold for splitting FIXFIX-frames into 2 env */ FIXP_DBL split_thr_m; /* Threshold for splitting FIXFIX-frames into 2 env */
INT split_thr_e; /* Scale for splitting threshold */
FIXP_DBL prevLowBandEnergy; /* Energy of low band */ FIXP_DBL prevLowBandEnergy; /* Energy of low band */
FIXP_DBL prevHighBandEnergy; /* Energy of high band */ FIXP_DBL prevHighBandEnergy; /* Energy of high band */
INT tran_fc; /* Number of lowband subbands to discard */ INT tran_fc; /* Number of lowband subbands to discard */
@ -112,6 +113,57 @@ SBR_TRANSIENT_DETECTOR;
typedef SBR_TRANSIENT_DETECTOR *HANDLE_SBR_TRANSIENT_DETECTOR; typedef SBR_TRANSIENT_DETECTOR *HANDLE_SBR_TRANSIENT_DETECTOR;
#define TRAN_DET_LOOKAHEAD 2
#define TRAN_DET_START_FREQ 4500 /*start frequency for transient detection*/
#define TRAN_DET_STOP_FREQ 13500 /*stop frequency for transient detection*/
#define TRAN_DET_MIN_QMFBANDS 4 /* minimum qmf bands for transient detection */
#define QMF_HP_dBd_SLOPE_FIX FL2FXCONST_DBL(0.00075275f) /* 0.002266f/10 * log2(10) */
#define TRAN_DET_THRSHLD FL2FXCONST_DBL(3.2f/4.f)
#define TRAN_DET_THRSHLD_SCALE (2)
typedef struct
{
INT transientCandidates[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
INT nTimeSlots;
INT lookahead;
INT startBand;
INT stopBand;
FIXP_DBL dBf_m[QMF_CHANNELS];
INT dBf_e[QMF_CHANNELS];
FIXP_DBL energy_timeSlots[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
INT energy_timeSlots_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
FIXP_DBL delta_energy[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
INT delta_energy_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
FIXP_DBL lowpass_energy[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
INT lowpass_energy_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
#if defined (FTD_LOG)
FDKFILE *ftd_log;
#endif
}
FAST_TRAN_DETECTOR;
typedef FAST_TRAN_DETECTOR *HANDLE_FAST_TRAN_DET;
INT FDKsbrEnc_InitSbrFastTransientDetector(
HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
const INT time_slots_per_frame,
const INT bandwidth_qmf_slot,
const INT no_qmf_channels,
const INT sbr_qmf_1st_band
);
void FDKsbrEnc_fastTransientDetect(
const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
const FIXP_DBL *const *Energies,
const int *const scaleEnergies,
const INT YBufferWriteOffset,
UCHAR *const tran_vector
);
void void
FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
FIXP_DBL **Energies, FIXP_DBL **Energies,
@ -124,6 +176,7 @@ FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
int int
FDKsbrEnc_InitSbrTransientDetector (HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, FDKsbrEnc_InitSbrTransientDetector (HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
INT frameSize, INT frameSize,
INT sampleFreq, INT sampleFreq,
sbrConfigurationPtr params, sbrConfigurationPtr params,
@ -145,6 +198,6 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
int YBufferSzShift, int YBufferSzShift,
int nSfb, int nSfb,
int timeStep, int timeStep,
int no_cols); int no_cols,
FIXP_DBL* tonality);
#endif #endif

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -134,13 +134,7 @@ typedef enum
TT_MP4_LOAS = 10, /**< Audio Sync Stream. */ TT_MP4_LOAS = 10, /**< Audio Sync Stream. */
TT_DRM = 12, /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */ TT_DRM = 12 /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
TT_MP1_L1 = 16, /**< MPEG 1 Audio Layer 1 audio bitstream. */
TT_MP1_L2 = 17, /**< MPEG 1 Audio Layer 2 audio bitstream. */
TT_MP1_L3 = 18, /**< MPEG 1 Audio Layer 3 audio bitstream. */
TT_RSVD50 = 50 /**< */
} TRANSPORT_TYPE; } TRANSPORT_TYPE;
@ -203,38 +197,22 @@ typedef enum
AOT_SAOC = 43, /**< SAOC */ AOT_SAOC = 43, /**< SAOC */
AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */
/* Pseudo AOTs */ /* Pseudo AOTs */
AOT_MP2_AAC_MAIN = 128, /**< Virtual AOT MP2 Main profile */
AOT_MP2_AAC_LC = 129, /**< Virtual AOT MP2 Low Complexity profile */
AOT_MP2_AAC_SSR = 130, /**< Virtual AOT MP2 Scalable Sampling Rate profile */
AOT_MP2_SBR = 132, /**< Virtual AOT MP2 Low Complexity Profile with SBR */
AOT_DAB = 134, /**< Virtual AOT for DAB (Layer2 with scalefactor CRC) */
AOT_DABPLUS_AAC_LC = 135, /**< Virtual AOT for DAB plus AAC-LC */
AOT_DABPLUS_SBR = 136, /**< Virtual AOT for DAB plus HE-AAC */
AOT_DABPLUS_PS = 137, /**< Virtual AOT for DAB plus HE-AAC v2 */
AOT_PLAIN_MP1 = 140, /**< Virtual AOT for plain mp1 */
AOT_PLAIN_MP2 = 141, /**< Virtual AOT for plain mp2 */
AOT_PLAIN_MP3 = 142, /**< Virtual AOT for plain mp3 */
AOT_DRM_AAC = 143, /**< Virtual AOT for DRM (ER-AAC-SCAL without SBR) */ AOT_DRM_AAC = 143, /**< Virtual AOT for DRM (ER-AAC-SCAL without SBR) */
AOT_DRM_SBR = 144, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR) */ AOT_DRM_SBR = 144, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR) */
AOT_DRM_MPEG_PS = 145, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */ AOT_DRM_MPEG_PS = 145 /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */
AOT_DRM_SURROUND = 146, /**< Virtual AOT for DRM Surround (ER-AAC-SCAL (+SBR) +MPS) */
AOT_MP2_PS = 156, /**< Virtual AOT MP2 Low Complexity Profile with SBR and PS */
AOT_MPEGS_RESIDUALS = 256 /**< Virtual AOT for MPEG Surround residuals */
} AUDIO_OBJECT_TYPE; } AUDIO_OBJECT_TYPE;
#define CAN_DO_PS(aot) \
((aot) == AOT_AAC_LC \
|| (aot) == AOT_SBR \
|| (aot) == AOT_PS \
|| (aot) == AOT_ER_BSAC \
|| (aot) == AOT_DRM_AAC)
#define IS_USAC(aot) \ #define IS_USAC(aot) \
((aot) == AOT_USAC \ ((aot) == AOT_USAC)
|| (aot) == AOT_RSVD50)
#define IS_LOWDELAY(aot) \ #define IS_LOWDELAY(aot) \
((aot) == AOT_ER_AAC_LD \ ((aot) == AOT_ER_AAC_LD \

View File

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

View File

@ -2,7 +2,7 @@
/* ----------------------------------------------------------------------------------------------------------- /* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. © Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -99,10 +99,15 @@ amm-info@iis.fraunhofer.de
/* library info */ /* library info */
#define SYS_LIB_VL0 1 #define SYS_LIB_VL0 1
#define SYS_LIB_VL1 3 #define SYS_LIB_VL1 3
#define SYS_LIB_VL2 6 #define SYS_LIB_VL2 8
#define SYS_LIB_TITLE "System Integration Library" #define SYS_LIB_TITLE "System Integration Library"
#ifdef __ANDROID__
#define SYS_LIB_BUILD_DATE ""
#define SYS_LIB_BUILD_TIME ""
#else
#define SYS_LIB_BUILD_DATE __DATE__ #define SYS_LIB_BUILD_DATE __DATE__
#define SYS_LIB_BUILD_TIME __TIME__ #define SYS_LIB_BUILD_TIME __TIME__
#endif
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -116,7 +121,7 @@ amm-info@iis.fraunhofer.de
/* Include OS/System specific implementations. */ /* Include OS/System specific implementations. */
#if defined(__linux__) /* cppp replaced: elif */ #if defined(__linux__) && !defined(__ANDROID__) /* cppp replaced: elif */
#include "linux/genericStds_linux.cpp" #include "linux/genericStds_linux.cpp"
#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__) */